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" 19252723Sdim#include "ARMConstantPoolValue.h" 20252723Sdim#include "ARMSubtarget.h" 21212793Sdim#include "ARMTargetMachine.h" 22226890Sdim#include "MCTargetDesc/ARMAddressingModes.h" 23263509Sdim#include "llvm/ADT/STLExtras.h" 24212793Sdim#include "llvm/CodeGen/Analysis.h" 25212793Sdim#include "llvm/CodeGen/FastISel.h" 26212793Sdim#include "llvm/CodeGen/FunctionLoweringInfo.h" 27212793Sdim#include "llvm/CodeGen/MachineConstantPool.h" 28212793Sdim#include "llvm/CodeGen/MachineFrameInfo.h" 29252723Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 30218893Sdim#include "llvm/CodeGen/MachineMemOperand.h" 31252723Sdim#include "llvm/CodeGen/MachineModuleInfo.h" 32212793Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 33252723Sdim#include "llvm/IR/CallingConv.h" 34252723Sdim#include "llvm/IR/DataLayout.h" 35252723Sdim#include "llvm/IR/DerivedTypes.h" 36252723Sdim#include "llvm/IR/GlobalVariable.h" 37252723Sdim#include "llvm/IR/Instructions.h" 38252723Sdim#include "llvm/IR/IntrinsicInst.h" 39252723Sdim#include "llvm/IR/Module.h" 40252723Sdim#include "llvm/IR/Operator.h" 41212793Sdim#include "llvm/Support/CallSite.h" 42212793Sdim#include "llvm/Support/CommandLine.h" 43212793Sdim#include "llvm/Support/ErrorHandling.h" 44212793Sdim#include "llvm/Support/GetElementPtrTypeIterator.h" 45212793Sdim#include "llvm/Target/TargetInstrInfo.h" 46212793Sdim#include "llvm/Target/TargetLowering.h" 47212793Sdim#include "llvm/Target/TargetMachine.h" 48212793Sdim#include "llvm/Target/TargetOptions.h" 49212793Sdimusing namespace llvm; 50212793Sdim 51218893Sdimextern cl::opt<bool> EnableARMLongCalls; 52218893Sdim 53212793Sdimnamespace { 54212793Sdim 55218893Sdim // All possible address modes, plus some. 56218893Sdim typedef struct Address { 57218893Sdim enum { 58218893Sdim RegBase, 59218893Sdim FrameIndexBase 60218893Sdim } BaseType; 61218893Sdim 62218893Sdim union { 63218893Sdim unsigned Reg; 64218893Sdim int FI; 65218893Sdim } Base; 66218893Sdim 67218893Sdim int Offset; 68218893Sdim 69218893Sdim // Innocuous defaults for our address. 70218893Sdim Address() 71223017Sdim : BaseType(RegBase), Offset(0) { 72218893Sdim Base.Reg = 0; 73218893Sdim } 74218893Sdim } Address; 75218893Sdim 76212793Sdimclass ARMFastISel : public FastISel { 77212793Sdim 78212793Sdim /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can 79212793Sdim /// make the right decision when generating code for different targets. 80212793Sdim const ARMSubtarget *Subtarget; 81212793Sdim const TargetMachine &TM; 82212793Sdim const TargetInstrInfo &TII; 83212793Sdim const TargetLowering &TLI; 84218893Sdim ARMFunctionInfo *AFI; 85212793Sdim 86218893Sdim // Convenience variables to avoid some queries. 87235633Sdim bool isThumb2; 88218893Sdim LLVMContext *Context; 89212793Sdim 90212793Sdim public: 91245431Sdim explicit ARMFastISel(FunctionLoweringInfo &funcInfo, 92245431Sdim const TargetLibraryInfo *libInfo) 93245431Sdim : FastISel(funcInfo, libInfo), 94212793Sdim TM(funcInfo.MF->getTarget()), 95212793Sdim TII(*TM.getInstrInfo()), 96212793Sdim TLI(*TM.getTargetLowering()) { 97212793Sdim Subtarget = &TM.getSubtarget<ARMSubtarget>(); 98212793Sdim AFI = funcInfo.MF->getInfo<ARMFunctionInfo>(); 99235633Sdim isThumb2 = AFI->isThumbFunction(); 100218893Sdim Context = &funcInfo.Fn->getContext(); 101212793Sdim } 102212793Sdim 103212793Sdim // Code from FastISel.cpp. 104245431Sdim private: 105245431Sdim unsigned FastEmitInst_(unsigned MachineInstOpcode, 106245431Sdim const TargetRegisterClass *RC); 107245431Sdim unsigned FastEmitInst_r(unsigned MachineInstOpcode, 108245431Sdim const TargetRegisterClass *RC, 109245431Sdim unsigned Op0, bool Op0IsKill); 110245431Sdim unsigned FastEmitInst_rr(unsigned MachineInstOpcode, 111245431Sdim const TargetRegisterClass *RC, 112245431Sdim unsigned Op0, bool Op0IsKill, 113245431Sdim unsigned Op1, bool Op1IsKill); 114245431Sdim unsigned FastEmitInst_rrr(unsigned MachineInstOpcode, 115245431Sdim const TargetRegisterClass *RC, 116245431Sdim unsigned Op0, bool Op0IsKill, 117245431Sdim unsigned Op1, bool Op1IsKill, 118245431Sdim unsigned Op2, bool Op2IsKill); 119245431Sdim unsigned FastEmitInst_ri(unsigned MachineInstOpcode, 120245431Sdim const TargetRegisterClass *RC, 121245431Sdim unsigned Op0, bool Op0IsKill, 122245431Sdim uint64_t Imm); 123245431Sdim unsigned FastEmitInst_rf(unsigned MachineInstOpcode, 124245431Sdim const TargetRegisterClass *RC, 125245431Sdim unsigned Op0, bool Op0IsKill, 126245431Sdim const ConstantFP *FPImm); 127245431Sdim unsigned FastEmitInst_rri(unsigned MachineInstOpcode, 128245431Sdim const TargetRegisterClass *RC, 129245431Sdim unsigned Op0, bool Op0IsKill, 130245431Sdim unsigned Op1, bool Op1IsKill, 131245431Sdim uint64_t Imm); 132245431Sdim unsigned FastEmitInst_i(unsigned MachineInstOpcode, 133245431Sdim const TargetRegisterClass *RC, 134245431Sdim uint64_t Imm); 135245431Sdim unsigned FastEmitInst_ii(unsigned MachineInstOpcode, 136245431Sdim const TargetRegisterClass *RC, 137245431Sdim uint64_t Imm1, uint64_t Imm2); 138221345Sdim 139245431Sdim unsigned FastEmitInst_extractsubreg(MVT RetVT, 140245431Sdim unsigned Op0, bool Op0IsKill, 141245431Sdim uint32_t Idx); 142218893Sdim 143212793Sdim // Backend specific FastISel code. 144245431Sdim private: 145212793Sdim virtual bool TargetSelectInstruction(const Instruction *I); 146212793Sdim virtual unsigned TargetMaterializeConstant(const Constant *C); 147218893Sdim virtual unsigned TargetMaterializeAlloca(const AllocaInst *AI); 148252723Sdim virtual bool tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo, 149252723Sdim const LoadInst *LI); 150252723Sdim virtual bool FastLowerArguments(); 151245431Sdim private: 152212793Sdim #include "ARMGenFastISel.inc" 153218893Sdim 154212793Sdim // Instruction selection routines. 155218893Sdim private: 156218893Sdim bool SelectLoad(const Instruction *I); 157218893Sdim bool SelectStore(const Instruction *I); 158218893Sdim bool SelectBranch(const Instruction *I); 159235633Sdim bool SelectIndirectBr(const Instruction *I); 160218893Sdim bool SelectCmp(const Instruction *I); 161218893Sdim bool SelectFPExt(const Instruction *I); 162218893Sdim bool SelectFPTrunc(const Instruction *I); 163235633Sdim bool SelectBinaryIntOp(const Instruction *I, unsigned ISDOpcode); 164235633Sdim bool SelectBinaryFPOp(const Instruction *I, unsigned ISDOpcode); 165235633Sdim bool SelectIToFP(const Instruction *I, bool isSigned); 166235633Sdim bool SelectFPToI(const Instruction *I, bool isSigned); 167235633Sdim bool SelectDiv(const Instruction *I, bool isSigned); 168235633Sdim bool SelectRem(const Instruction *I, bool isSigned); 169235633Sdim bool SelectCall(const Instruction *I, const char *IntrMemName); 170235633Sdim bool SelectIntrinsicCall(const IntrinsicInst &I); 171218893Sdim bool SelectSelect(const Instruction *I); 172218893Sdim bool SelectRet(const Instruction *I); 173235633Sdim bool SelectTrunc(const Instruction *I); 174235633Sdim bool SelectIntExt(const Instruction *I); 175245431Sdim bool SelectShift(const Instruction *I, ARM_AM::ShiftOpc ShiftTy); 176212793Sdim 177212793Sdim // Utility routines. 178212793Sdim private: 179263509Sdim unsigned constrainOperandRegClass(const MCInstrDesc &II, unsigned OpNum, 180263509Sdim unsigned Op); 181226890Sdim bool isTypeLegal(Type *Ty, MVT &VT); 182226890Sdim bool isLoadTypeLegal(Type *Ty, MVT &VT); 183235633Sdim bool ARMEmitCmp(const Value *Src1Value, const Value *Src2Value, 184235633Sdim bool isZExt); 185252723Sdim bool ARMEmitLoad(MVT VT, unsigned &ResultReg, Address &Addr, 186235633Sdim unsigned Alignment = 0, bool isZExt = true, 187235633Sdim bool allocReg = true); 188252723Sdim bool ARMEmitStore(MVT VT, unsigned SrcReg, Address &Addr, 189235633Sdim unsigned Alignment = 0); 190218893Sdim bool ARMComputeAddress(const Value *Obj, Address &Addr); 191252723Sdim void ARMSimplifyAddress(Address &Addr, MVT VT, bool useAM3); 192235633Sdim bool ARMIsMemCpySmall(uint64_t Len); 193252723Sdim bool ARMTryEmitSmallMemCpy(Address Dest, Address Src, uint64_t Len, 194252723Sdim unsigned Alignment); 195252723Sdim unsigned ARMEmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, bool isZExt); 196252723Sdim unsigned ARMMaterializeFP(const ConstantFP *CFP, MVT VT); 197252723Sdim unsigned ARMMaterializeInt(const Constant *C, MVT VT); 198252723Sdim unsigned ARMMaterializeGV(const GlobalValue *GV, MVT VT); 199252723Sdim unsigned ARMMoveToFPReg(MVT VT, unsigned SrcReg); 200252723Sdim unsigned ARMMoveToIntReg(MVT VT, unsigned SrcReg); 201245431Sdim unsigned ARMSelectCallOp(bool UseReg); 202252723Sdim unsigned ARMLowerPICELF(const GlobalValue *GV, unsigned Align, MVT VT); 203218893Sdim 204218893Sdim // Call handling routines. 205218893Sdim private: 206245431Sdim CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, 207245431Sdim bool Return, 208245431Sdim bool isVarArg); 209218893Sdim bool ProcessCallArgs(SmallVectorImpl<Value*> &Args, 210218893Sdim SmallVectorImpl<unsigned> &ArgRegs, 211218893Sdim SmallVectorImpl<MVT> &ArgVTs, 212218893Sdim SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags, 213218893Sdim SmallVectorImpl<unsigned> &RegArgs, 214218893Sdim CallingConv::ID CC, 215245431Sdim unsigned &NumBytes, 216245431Sdim bool isVarArg); 217245431Sdim unsigned getLibcallReg(const Twine &Name); 218218893Sdim bool FinishCall(MVT RetVT, SmallVectorImpl<unsigned> &UsedRegs, 219218893Sdim const Instruction *I, CallingConv::ID CC, 220245431Sdim unsigned &NumBytes, bool isVarArg); 221218893Sdim bool ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call); 222218893Sdim 223218893Sdim // OptionalDef handling routines. 224218893Sdim private: 225221345Sdim bool isARMNEONPred(const MachineInstr *MI); 226212793Sdim bool DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR); 227212793Sdim const MachineInstrBuilder &AddOptionalDefs(const MachineInstrBuilder &MIB); 228252723Sdim void AddLoadStoreOperands(MVT VT, Address &Addr, 229223017Sdim const MachineInstrBuilder &MIB, 230235633Sdim unsigned Flags, bool useAM3); 231212793Sdim}; 232212793Sdim 233212793Sdim} // end anonymous namespace 234212793Sdim 235218893Sdim#include "ARMGenCallingConv.inc" 236212793Sdim 237212793Sdim// DefinesOptionalPredicate - This is different from DefinesPredicate in that 238212793Sdim// we don't care about implicit defs here, just places we'll need to add a 239212793Sdim// default CCReg argument. Sets CPSR if we're setting CPSR instead of CCR. 240212793Sdimbool ARMFastISel::DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR) { 241235633Sdim if (!MI->hasOptionalDef()) 242212793Sdim return false; 243212793Sdim 244212793Sdim // Look to see if our OptionalDef is defining CPSR or CCR. 245212793Sdim for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 246212793Sdim const MachineOperand &MO = MI->getOperand(i); 247212793Sdim if (!MO.isReg() || !MO.isDef()) continue; 248212793Sdim if (MO.getReg() == ARM::CPSR) 249212793Sdim *CPSR = true; 250212793Sdim } 251212793Sdim return true; 252212793Sdim} 253212793Sdim 254221345Sdimbool ARMFastISel::isARMNEONPred(const MachineInstr *MI) { 255224145Sdim const MCInstrDesc &MCID = MI->getDesc(); 256221345Sdim 257263509Sdim // If we're a thumb2 or not NEON function we'll be handled via isPredicable. 258224145Sdim if ((MCID.TSFlags & ARMII::DomainMask) != ARMII::DomainNEON || 259221345Sdim AFI->isThumb2Function()) 260263509Sdim return MI->isPredicable(); 261221345Sdim 262224145Sdim for (unsigned i = 0, e = MCID.getNumOperands(); i != e; ++i) 263224145Sdim if (MCID.OpInfo[i].isPredicate()) 264221345Sdim return true; 265221345Sdim 266221345Sdim return false; 267221345Sdim} 268221345Sdim 269212793Sdim// If the machine is predicable go ahead and add the predicate operands, if 270212793Sdim// it needs default CC operands add those. 271218893Sdim// TODO: If we want to support thumb1 then we'll need to deal with optional 272218893Sdim// CPSR defs that need to be added before the remaining operands. See s_cc_out 273218893Sdim// for descriptions why. 274212793Sdimconst MachineInstrBuilder & 275212793SdimARMFastISel::AddOptionalDefs(const MachineInstrBuilder &MIB) { 276212793Sdim MachineInstr *MI = &*MIB; 277212793Sdim 278221345Sdim // Do we use a predicate? or... 279221345Sdim // Are we NEON in ARM mode and have a predicate operand? If so, I know 280221345Sdim // we're not predicable but add it anyways. 281263509Sdim if (isARMNEONPred(MI)) 282212793Sdim AddDefaultPred(MIB); 283218893Sdim 284212793Sdim // Do we optionally set a predicate? Preds is size > 0 iff the predicate 285212793Sdim // defines CPSR. All other OptionalDefines in ARM are the CCR register. 286212793Sdim bool CPSR = false; 287212793Sdim if (DefinesOptionalPredicate(MI, &CPSR)) { 288212793Sdim if (CPSR) 289212793Sdim AddDefaultT1CC(MIB); 290212793Sdim else 291212793Sdim AddDefaultCC(MIB); 292212793Sdim } 293212793Sdim return MIB; 294212793Sdim} 295212793Sdim 296263509Sdimunsigned ARMFastISel::constrainOperandRegClass(const MCInstrDesc &II, 297263509Sdim unsigned Op, unsigned OpNum) { 298263509Sdim if (TargetRegisterInfo::isVirtualRegister(Op)) { 299263509Sdim const TargetRegisterClass *RegClass = 300263509Sdim TII.getRegClass(II, OpNum, &TRI, *FuncInfo.MF); 301263509Sdim if (!MRI.constrainRegClass(Op, RegClass)) { 302263509Sdim // If it's not legal to COPY between the register classes, something 303263509Sdim // has gone very wrong before we got here. 304263509Sdim unsigned NewOp = createResultReg(RegClass); 305263509Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 306263509Sdim TII.get(TargetOpcode::COPY), NewOp).addReg(Op)); 307263509Sdim return NewOp; 308263509Sdim } 309263509Sdim } 310263509Sdim return Op; 311263509Sdim} 312263509Sdim 313212793Sdimunsigned ARMFastISel::FastEmitInst_(unsigned MachineInstOpcode, 314212793Sdim const TargetRegisterClass* RC) { 315212793Sdim unsigned ResultReg = createResultReg(RC); 316224145Sdim const MCInstrDesc &II = TII.get(MachineInstOpcode); 317212793Sdim 318212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)); 319212793Sdim return ResultReg; 320212793Sdim} 321212793Sdim 322212793Sdimunsigned ARMFastISel::FastEmitInst_r(unsigned MachineInstOpcode, 323212793Sdim const TargetRegisterClass *RC, 324212793Sdim unsigned Op0, bool Op0IsKill) { 325212793Sdim unsigned ResultReg = createResultReg(RC); 326224145Sdim const MCInstrDesc &II = TII.get(MachineInstOpcode); 327212793Sdim 328263509Sdim // Make sure the input operand is sufficiently constrained to be legal 329263509Sdim // for this instruction. 330263509Sdim Op0 = constrainOperandRegClass(II, Op0, 1); 331235633Sdim if (II.getNumDefs() >= 1) { 332212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg) 333212793Sdim .addReg(Op0, Op0IsKill * RegState::Kill)); 334235633Sdim } else { 335212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) 336212793Sdim .addReg(Op0, Op0IsKill * RegState::Kill)); 337212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 338212793Sdim TII.get(TargetOpcode::COPY), ResultReg) 339212793Sdim .addReg(II.ImplicitDefs[0])); 340212793Sdim } 341212793Sdim return ResultReg; 342212793Sdim} 343212793Sdim 344212793Sdimunsigned ARMFastISel::FastEmitInst_rr(unsigned MachineInstOpcode, 345212793Sdim const TargetRegisterClass *RC, 346212793Sdim unsigned Op0, bool Op0IsKill, 347212793Sdim unsigned Op1, bool Op1IsKill) { 348212793Sdim unsigned ResultReg = createResultReg(RC); 349224145Sdim const MCInstrDesc &II = TII.get(MachineInstOpcode); 350212793Sdim 351263509Sdim // Make sure the input operands are sufficiently constrained to be legal 352263509Sdim // for this instruction. 353263509Sdim Op0 = constrainOperandRegClass(II, Op0, 1); 354263509Sdim Op1 = constrainOperandRegClass(II, Op1, 2); 355263509Sdim 356235633Sdim if (II.getNumDefs() >= 1) { 357212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg) 358212793Sdim .addReg(Op0, Op0IsKill * RegState::Kill) 359212793Sdim .addReg(Op1, Op1IsKill * RegState::Kill)); 360235633Sdim } else { 361212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) 362212793Sdim .addReg(Op0, Op0IsKill * RegState::Kill) 363212793Sdim .addReg(Op1, Op1IsKill * RegState::Kill)); 364212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 365212793Sdim TII.get(TargetOpcode::COPY), ResultReg) 366212793Sdim .addReg(II.ImplicitDefs[0])); 367212793Sdim } 368212793Sdim return ResultReg; 369212793Sdim} 370212793Sdim 371221345Sdimunsigned ARMFastISel::FastEmitInst_rrr(unsigned MachineInstOpcode, 372221345Sdim const TargetRegisterClass *RC, 373221345Sdim unsigned Op0, bool Op0IsKill, 374221345Sdim unsigned Op1, bool Op1IsKill, 375221345Sdim unsigned Op2, bool Op2IsKill) { 376221345Sdim unsigned ResultReg = createResultReg(RC); 377224145Sdim const MCInstrDesc &II = TII.get(MachineInstOpcode); 378221345Sdim 379263509Sdim // Make sure the input operands are sufficiently constrained to be legal 380263509Sdim // for this instruction. 381263509Sdim Op0 = constrainOperandRegClass(II, Op0, 1); 382263509Sdim Op1 = constrainOperandRegClass(II, Op1, 2); 383263509Sdim Op2 = constrainOperandRegClass(II, Op1, 3); 384263509Sdim 385235633Sdim if (II.getNumDefs() >= 1) { 386221345Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg) 387221345Sdim .addReg(Op0, Op0IsKill * RegState::Kill) 388221345Sdim .addReg(Op1, Op1IsKill * RegState::Kill) 389221345Sdim .addReg(Op2, Op2IsKill * RegState::Kill)); 390235633Sdim } else { 391221345Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) 392221345Sdim .addReg(Op0, Op0IsKill * RegState::Kill) 393221345Sdim .addReg(Op1, Op1IsKill * RegState::Kill) 394221345Sdim .addReg(Op2, Op2IsKill * RegState::Kill)); 395221345Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 396221345Sdim TII.get(TargetOpcode::COPY), ResultReg) 397221345Sdim .addReg(II.ImplicitDefs[0])); 398221345Sdim } 399221345Sdim return ResultReg; 400221345Sdim} 401221345Sdim 402212793Sdimunsigned ARMFastISel::FastEmitInst_ri(unsigned MachineInstOpcode, 403212793Sdim const TargetRegisterClass *RC, 404212793Sdim unsigned Op0, bool Op0IsKill, 405212793Sdim uint64_t Imm) { 406212793Sdim unsigned ResultReg = createResultReg(RC); 407224145Sdim const MCInstrDesc &II = TII.get(MachineInstOpcode); 408212793Sdim 409263509Sdim // Make sure the input operand is sufficiently constrained to be legal 410263509Sdim // for this instruction. 411263509Sdim Op0 = constrainOperandRegClass(II, Op0, 1); 412235633Sdim if (II.getNumDefs() >= 1) { 413212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg) 414212793Sdim .addReg(Op0, Op0IsKill * RegState::Kill) 415212793Sdim .addImm(Imm)); 416235633Sdim } else { 417212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) 418212793Sdim .addReg(Op0, Op0IsKill * RegState::Kill) 419212793Sdim .addImm(Imm)); 420212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 421212793Sdim TII.get(TargetOpcode::COPY), ResultReg) 422212793Sdim .addReg(II.ImplicitDefs[0])); 423212793Sdim } 424212793Sdim return ResultReg; 425212793Sdim} 426212793Sdim 427212793Sdimunsigned ARMFastISel::FastEmitInst_rf(unsigned MachineInstOpcode, 428212793Sdim const TargetRegisterClass *RC, 429212793Sdim unsigned Op0, bool Op0IsKill, 430212793Sdim const ConstantFP *FPImm) { 431212793Sdim unsigned ResultReg = createResultReg(RC); 432224145Sdim const MCInstrDesc &II = TII.get(MachineInstOpcode); 433212793Sdim 434263509Sdim // Make sure the input operand is sufficiently constrained to be legal 435263509Sdim // for this instruction. 436263509Sdim Op0 = constrainOperandRegClass(II, Op0, 1); 437235633Sdim if (II.getNumDefs() >= 1) { 438212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg) 439212793Sdim .addReg(Op0, Op0IsKill * RegState::Kill) 440212793Sdim .addFPImm(FPImm)); 441235633Sdim } else { 442212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) 443212793Sdim .addReg(Op0, Op0IsKill * RegState::Kill) 444212793Sdim .addFPImm(FPImm)); 445212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 446212793Sdim TII.get(TargetOpcode::COPY), ResultReg) 447212793Sdim .addReg(II.ImplicitDefs[0])); 448212793Sdim } 449212793Sdim return ResultReg; 450212793Sdim} 451212793Sdim 452212793Sdimunsigned ARMFastISel::FastEmitInst_rri(unsigned MachineInstOpcode, 453212793Sdim const TargetRegisterClass *RC, 454212793Sdim unsigned Op0, bool Op0IsKill, 455212793Sdim unsigned Op1, bool Op1IsKill, 456212793Sdim uint64_t Imm) { 457212793Sdim unsigned ResultReg = createResultReg(RC); 458224145Sdim const MCInstrDesc &II = TII.get(MachineInstOpcode); 459212793Sdim 460263509Sdim // Make sure the input operands are sufficiently constrained to be legal 461263509Sdim // for this instruction. 462263509Sdim Op0 = constrainOperandRegClass(II, Op0, 1); 463263509Sdim Op1 = constrainOperandRegClass(II, Op1, 2); 464235633Sdim if (II.getNumDefs() >= 1) { 465212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg) 466212793Sdim .addReg(Op0, Op0IsKill * RegState::Kill) 467212793Sdim .addReg(Op1, Op1IsKill * RegState::Kill) 468212793Sdim .addImm(Imm)); 469235633Sdim } else { 470212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) 471212793Sdim .addReg(Op0, Op0IsKill * RegState::Kill) 472212793Sdim .addReg(Op1, Op1IsKill * RegState::Kill) 473212793Sdim .addImm(Imm)); 474212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 475212793Sdim TII.get(TargetOpcode::COPY), ResultReg) 476212793Sdim .addReg(II.ImplicitDefs[0])); 477212793Sdim } 478212793Sdim return ResultReg; 479212793Sdim} 480212793Sdim 481212793Sdimunsigned ARMFastISel::FastEmitInst_i(unsigned MachineInstOpcode, 482212793Sdim const TargetRegisterClass *RC, 483212793Sdim uint64_t Imm) { 484212793Sdim unsigned ResultReg = createResultReg(RC); 485224145Sdim const MCInstrDesc &II = TII.get(MachineInstOpcode); 486218893Sdim 487235633Sdim if (II.getNumDefs() >= 1) { 488212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg) 489212793Sdim .addImm(Imm)); 490235633Sdim } else { 491212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) 492212793Sdim .addImm(Imm)); 493212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 494212793Sdim TII.get(TargetOpcode::COPY), ResultReg) 495212793Sdim .addReg(II.ImplicitDefs[0])); 496212793Sdim } 497212793Sdim return ResultReg; 498212793Sdim} 499212793Sdim 500221345Sdimunsigned ARMFastISel::FastEmitInst_ii(unsigned MachineInstOpcode, 501221345Sdim const TargetRegisterClass *RC, 502221345Sdim uint64_t Imm1, uint64_t Imm2) { 503221345Sdim unsigned ResultReg = createResultReg(RC); 504224145Sdim const MCInstrDesc &II = TII.get(MachineInstOpcode); 505223017Sdim 506235633Sdim if (II.getNumDefs() >= 1) { 507221345Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg) 508221345Sdim .addImm(Imm1).addImm(Imm2)); 509235633Sdim } else { 510221345Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) 511221345Sdim .addImm(Imm1).addImm(Imm2)); 512223017Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 513221345Sdim TII.get(TargetOpcode::COPY), 514221345Sdim ResultReg) 515221345Sdim .addReg(II.ImplicitDefs[0])); 516221345Sdim } 517221345Sdim return ResultReg; 518221345Sdim} 519221345Sdim 520212793Sdimunsigned ARMFastISel::FastEmitInst_extractsubreg(MVT RetVT, 521212793Sdim unsigned Op0, bool Op0IsKill, 522212793Sdim uint32_t Idx) { 523212793Sdim unsigned ResultReg = createResultReg(TLI.getRegClassFor(RetVT)); 524212793Sdim assert(TargetRegisterInfo::isVirtualRegister(Op0) && 525212793Sdim "Cannot yet extract from physregs"); 526235633Sdim 527212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, 528235633Sdim DL, TII.get(TargetOpcode::COPY), ResultReg) 529235633Sdim .addReg(Op0, getKillRegState(Op0IsKill), Idx)); 530212793Sdim return ResultReg; 531212793Sdim} 532212793Sdim 533218893Sdim// TODO: Don't worry about 64-bit now, but when this is fixed remove the 534218893Sdim// checks from the various callers. 535252723Sdimunsigned ARMFastISel::ARMMoveToFPReg(MVT VT, unsigned SrcReg) { 536218893Sdim if (VT == MVT::f64) return 0; 537212793Sdim 538218893Sdim unsigned MoveReg = createResultReg(TLI.getRegClassFor(VT)); 539218893Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 540235633Sdim TII.get(ARM::VMOVSR), MoveReg) 541218893Sdim .addReg(SrcReg)); 542218893Sdim return MoveReg; 543218893Sdim} 544212793Sdim 545252723Sdimunsigned ARMFastISel::ARMMoveToIntReg(MVT VT, unsigned SrcReg) { 546218893Sdim if (VT == MVT::i64) return 0; 547218893Sdim 548218893Sdim unsigned MoveReg = createResultReg(TLI.getRegClassFor(VT)); 549218893Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 550235633Sdim TII.get(ARM::VMOVRS), MoveReg) 551218893Sdim .addReg(SrcReg)); 552218893Sdim return MoveReg; 553218893Sdim} 554218893Sdim 555218893Sdim// For double width floating point we need to materialize two constants 556218893Sdim// (the high and the low) into integer registers then use a move to get 557218893Sdim// the combined constant into an FP reg. 558252723Sdimunsigned ARMFastISel::ARMMaterializeFP(const ConstantFP *CFP, MVT VT) { 559218893Sdim const APFloat Val = CFP->getValueAPF(); 560218893Sdim bool is64bit = VT == MVT::f64; 561218893Sdim 562218893Sdim // This checks to see if we can use VFP3 instructions to materialize 563218893Sdim // a constant, otherwise we have to go through the constant pool. 564218893Sdim if (TLI.isFPImmLegal(Val, VT)) { 565226890Sdim int Imm; 566226890Sdim unsigned Opc; 567226890Sdim if (is64bit) { 568226890Sdim Imm = ARM_AM::getFP64Imm(Val); 569226890Sdim Opc = ARM::FCONSTD; 570226890Sdim } else { 571226890Sdim Imm = ARM_AM::getFP32Imm(Val); 572226890Sdim Opc = ARM::FCONSTS; 573226890Sdim } 574218893Sdim unsigned DestReg = createResultReg(TLI.getRegClassFor(VT)); 575218893Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), 576218893Sdim DestReg) 577226890Sdim .addImm(Imm)); 578218893Sdim return DestReg; 579218893Sdim } 580218893Sdim 581218893Sdim // Require VFP2 for loading fp constants. 582218893Sdim if (!Subtarget->hasVFP2()) return false; 583218893Sdim 584212793Sdim // MachineConstantPool wants an explicit alignment. 585218893Sdim unsigned Align = TD.getPrefTypeAlignment(CFP->getType()); 586218893Sdim if (Align == 0) { 587218893Sdim // TODO: Figure out if this is correct. 588218893Sdim Align = TD.getTypeAllocSize(CFP->getType()); 589218893Sdim } 590218893Sdim unsigned Idx = MCP.getConstantPoolIndex(cast<Constant>(CFP), Align); 591218893Sdim unsigned DestReg = createResultReg(TLI.getRegClassFor(VT)); 592218893Sdim unsigned Opc = is64bit ? ARM::VLDRD : ARM::VLDRS; 593218893Sdim 594218893Sdim // The extra reg is for addrmode5. 595218893Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), 596218893Sdim DestReg) 597218893Sdim .addConstantPoolIndex(Idx) 598218893Sdim .addReg(0)); 599218893Sdim return DestReg; 600218893Sdim} 601218893Sdim 602252723Sdimunsigned ARMFastISel::ARMMaterializeInt(const Constant *C, MVT VT) { 603218893Sdim 604235633Sdim if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1) 605235633Sdim return false; 606218893Sdim 607218893Sdim // If we can do this in a single instruction without a constant pool entry 608218893Sdim // do so now. 609218893Sdim const ConstantInt *CI = cast<ConstantInt>(C); 610235633Sdim if (Subtarget->hasV6T2Ops() && isUInt<16>(CI->getZExtValue())) { 611235633Sdim unsigned Opc = isThumb2 ? ARM::t2MOVi16 : ARM::MOVi16; 612252723Sdim const TargetRegisterClass *RC = isThumb2 ? &ARM::rGPRRegClass : 613252723Sdim &ARM::GPRRegClass; 614252723Sdim unsigned ImmReg = createResultReg(RC); 615218893Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 616235633Sdim TII.get(Opc), ImmReg) 617235633Sdim .addImm(CI->getZExtValue())); 618235633Sdim return ImmReg; 619218893Sdim } 620218893Sdim 621235633Sdim // Use MVN to emit negative constants. 622235633Sdim if (VT == MVT::i32 && Subtarget->hasV6T2Ops() && CI->isNegative()) { 623235633Sdim unsigned Imm = (unsigned)~(CI->getSExtValue()); 624235633Sdim bool UseImm = isThumb2 ? (ARM_AM::getT2SOImmVal(Imm) != -1) : 625235633Sdim (ARM_AM::getSOImmVal(Imm) != -1); 626235633Sdim if (UseImm) { 627235633Sdim unsigned Opc = isThumb2 ? ARM::t2MVNi : ARM::MVNi; 628235633Sdim unsigned ImmReg = createResultReg(TLI.getRegClassFor(MVT::i32)); 629235633Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 630235633Sdim TII.get(Opc), ImmReg) 631235633Sdim .addImm(Imm)); 632235633Sdim return ImmReg; 633235633Sdim } 634235633Sdim } 635235633Sdim 636235633Sdim // Load from constant pool. For now 32-bit only. 637235633Sdim if (VT != MVT::i32) 638235633Sdim return false; 639235633Sdim 640235633Sdim unsigned DestReg = createResultReg(TLI.getRegClassFor(VT)); 641235633Sdim 642218893Sdim // MachineConstantPool wants an explicit alignment. 643212793Sdim unsigned Align = TD.getPrefTypeAlignment(C->getType()); 644212793Sdim if (Align == 0) { 645212793Sdim // TODO: Figure out if this is correct. 646212793Sdim Align = TD.getTypeAllocSize(C->getType()); 647212793Sdim } 648212793Sdim unsigned Idx = MCP.getConstantPoolIndex(C, Align); 649212793Sdim 650235633Sdim if (isThumb2) 651212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 652218893Sdim TII.get(ARM::t2LDRpci), DestReg) 653218893Sdim .addConstantPoolIndex(Idx)); 654212793Sdim else 655218893Sdim // The extra immediate is for addrmode2. 656263509Sdim DestReg = constrainOperandRegClass(TII.get(ARM::LDRcp), DestReg, 0); 657212793Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 658218893Sdim TII.get(ARM::LDRcp), DestReg) 659218893Sdim .addConstantPoolIndex(Idx) 660218893Sdim .addImm(0)); 661218893Sdim 662212793Sdim return DestReg; 663212793Sdim} 664212793Sdim 665252723Sdimunsigned ARMFastISel::ARMMaterializeGV(const GlobalValue *GV, MVT VT) { 666218893Sdim // For now 32-bit only. 667218893Sdim if (VT != MVT::i32) return 0; 668218893Sdim 669218893Sdim Reloc::Model RelocM = TM.getRelocationModel(); 670245431Sdim bool IsIndirect = Subtarget->GVIsIndirectSymbol(GV, RelocM); 671245431Sdim const TargetRegisterClass *RC = isThumb2 ? 672245431Sdim (const TargetRegisterClass*)&ARM::rGPRRegClass : 673245431Sdim (const TargetRegisterClass*)&ARM::GPRRegClass; 674245431Sdim unsigned DestReg = createResultReg(RC); 675218893Sdim 676263509Sdim // FastISel TLS support on non-Darwin is broken, punt to SelectionDAG. 677263509Sdim const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV); 678263509Sdim bool IsThreadLocal = GVar && GVar->isThreadLocal(); 679263509Sdim if (!Subtarget->isTargetDarwin() && IsThreadLocal) return 0; 680263509Sdim 681235633Sdim // Use movw+movt when possible, it avoids constant pool entries. 682235633Sdim // Darwin targets don't support movt with Reloc::Static, see 683235633Sdim // ARMTargetLowering::LowerGlobalAddressDarwin. Other targets only support 684235633Sdim // static movt relocations. 685235633Sdim if (Subtarget->useMovt() && 686235633Sdim Subtarget->isTargetDarwin() == (RelocM != Reloc::Static)) { 687235633Sdim unsigned Opc; 688235633Sdim switch (RelocM) { 689235633Sdim case Reloc::PIC_: 690235633Sdim Opc = isThumb2 ? ARM::t2MOV_ga_pcrel : ARM::MOV_ga_pcrel; 691235633Sdim break; 692235633Sdim case Reloc::DynamicNoPIC: 693235633Sdim Opc = isThumb2 ? ARM::t2MOV_ga_dyn : ARM::MOV_ga_dyn; 694235633Sdim break; 695235633Sdim default: 696235633Sdim Opc = isThumb2 ? ARM::t2MOVi32imm : ARM::MOVi32imm; 697235633Sdim break; 698235633Sdim } 699235633Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), 700235633Sdim DestReg).addGlobalAddress(GV)); 701235633Sdim } else { 702235633Sdim // MachineConstantPool wants an explicit alignment. 703235633Sdim unsigned Align = TD.getPrefTypeAlignment(GV->getType()); 704235633Sdim if (Align == 0) { 705235633Sdim // TODO: Figure out if this is correct. 706235633Sdim Align = TD.getTypeAllocSize(GV->getType()); 707235633Sdim } 708218893Sdim 709245431Sdim if (Subtarget->isTargetELF() && RelocM == Reloc::PIC_) 710245431Sdim return ARMLowerPICELF(GV, Align, VT); 711245431Sdim 712235633Sdim // Grab index. 713235633Sdim unsigned PCAdj = (RelocM != Reloc::PIC_) ? 0 : 714235633Sdim (Subtarget->isThumb() ? 4 : 8); 715235633Sdim unsigned Id = AFI->createPICLabelUId(); 716235633Sdim ARMConstantPoolValue *CPV = ARMConstantPoolConstant::Create(GV, Id, 717235633Sdim ARMCP::CPValue, 718235633Sdim PCAdj); 719235633Sdim unsigned Idx = MCP.getConstantPoolIndex(CPV, Align); 720235633Sdim 721235633Sdim // Load value. 722235633Sdim MachineInstrBuilder MIB; 723235633Sdim if (isThumb2) { 724235633Sdim unsigned Opc = (RelocM!=Reloc::PIC_) ? ARM::t2LDRpci : ARM::t2LDRpci_pic; 725235633Sdim MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), DestReg) 726235633Sdim .addConstantPoolIndex(Idx); 727235633Sdim if (RelocM == Reloc::PIC_) 728235633Sdim MIB.addImm(Id); 729245431Sdim AddOptionalDefs(MIB); 730235633Sdim } else { 731235633Sdim // The extra immediate is for addrmode2. 732263509Sdim DestReg = constrainOperandRegClass(TII.get(ARM::LDRcp), DestReg, 0); 733235633Sdim MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(ARM::LDRcp), 734235633Sdim DestReg) 735235633Sdim .addConstantPoolIndex(Idx) 736235633Sdim .addImm(0); 737245431Sdim AddOptionalDefs(MIB); 738245431Sdim 739245431Sdim if (RelocM == Reloc::PIC_) { 740245431Sdim unsigned Opc = IsIndirect ? ARM::PICLDR : ARM::PICADD; 741245431Sdim unsigned NewDestReg = createResultReg(TLI.getRegClassFor(VT)); 742245431Sdim 743245431Sdim MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, 744245431Sdim DL, TII.get(Opc), NewDestReg) 745245431Sdim .addReg(DestReg) 746245431Sdim .addImm(Id); 747245431Sdim AddOptionalDefs(MIB); 748245431Sdim return NewDestReg; 749245431Sdim } 750235633Sdim } 751218893Sdim } 752223017Sdim 753245431Sdim if (IsIndirect) { 754235633Sdim MachineInstrBuilder MIB; 755223017Sdim unsigned NewDestReg = createResultReg(TLI.getRegClassFor(VT)); 756235633Sdim if (isThumb2) 757226890Sdim MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 758226890Sdim TII.get(ARM::t2LDRi12), NewDestReg) 759223017Sdim .addReg(DestReg) 760223017Sdim .addImm(0); 761223017Sdim else 762223017Sdim MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(ARM::LDRi12), 763223017Sdim NewDestReg) 764223017Sdim .addReg(DestReg) 765223017Sdim .addImm(0); 766223017Sdim DestReg = NewDestReg; 767223017Sdim AddOptionalDefs(MIB); 768223017Sdim } 769223017Sdim 770218893Sdim return DestReg; 771218893Sdim} 772218893Sdim 773218893Sdimunsigned ARMFastISel::TargetMaterializeConstant(const Constant *C) { 774252723Sdim EVT CEVT = TLI.getValueType(C->getType(), true); 775218893Sdim 776212793Sdim // Only handle simple types. 777252723Sdim if (!CEVT.isSimple()) return 0; 778252723Sdim MVT VT = CEVT.getSimpleVT(); 779218893Sdim 780218893Sdim if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) 781218893Sdim return ARMMaterializeFP(CFP, VT); 782218893Sdim else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) 783218893Sdim return ARMMaterializeGV(GV, VT); 784218893Sdim else if (isa<ConstantInt>(C)) 785218893Sdim return ARMMaterializeInt(C, VT); 786218893Sdim 787218893Sdim return 0; 788218893Sdim} 789218893Sdim 790235633Sdim// TODO: unsigned ARMFastISel::TargetMaterializeFloatZero(const ConstantFP *CF); 791235633Sdim 792218893Sdimunsigned ARMFastISel::TargetMaterializeAlloca(const AllocaInst *AI) { 793218893Sdim // Don't handle dynamic allocas. 794218893Sdim if (!FuncInfo.StaticAllocaMap.count(AI)) return 0; 795218893Sdim 796218893Sdim MVT VT; 797245431Sdim if (!isLoadTypeLegal(AI->getType(), VT)) return 0; 798218893Sdim 799218893Sdim DenseMap<const AllocaInst*, int>::iterator SI = 800218893Sdim FuncInfo.StaticAllocaMap.find(AI); 801218893Sdim 802218893Sdim // This will get lowered later into the correct offsets and registers 803218893Sdim // via rewriteXFrameIndex. 804218893Sdim if (SI != FuncInfo.StaticAllocaMap.end()) { 805235633Sdim const TargetRegisterClass* RC = TLI.getRegClassFor(VT); 806218893Sdim unsigned ResultReg = createResultReg(RC); 807235633Sdim unsigned Opc = isThumb2 ? ARM::t2ADDri : ARM::ADDri; 808235633Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 809218893Sdim TII.get(Opc), ResultReg) 810218893Sdim .addFrameIndex(SI->second) 811218893Sdim .addImm(0)); 812218893Sdim return ResultReg; 813218893Sdim } 814218893Sdim 815218893Sdim return 0; 816218893Sdim} 817218893Sdim 818226890Sdimbool ARMFastISel::isTypeLegal(Type *Ty, MVT &VT) { 819218893Sdim EVT evt = TLI.getValueType(Ty, true); 820218893Sdim 821218893Sdim // Only handle simple types. 822218893Sdim if (evt == MVT::Other || !evt.isSimple()) return false; 823218893Sdim VT = evt.getSimpleVT(); 824218893Sdim 825212793Sdim // Handle all legal types, i.e. a register that will directly hold this 826212793Sdim // value. 827212793Sdim return TLI.isTypeLegal(VT); 828212793Sdim} 829212793Sdim 830226890Sdimbool ARMFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) { 831212793Sdim if (isTypeLegal(Ty, VT)) return true; 832218893Sdim 833212793Sdim // If this is a type than can be sign or zero-extended to a basic operation 834212793Sdim // go ahead and accept it now. 835235633Sdim if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16) 836212793Sdim return true; 837218893Sdim 838212793Sdim return false; 839212793Sdim} 840212793Sdim 841218893Sdim// Computes the address to get to an object. 842218893Sdimbool ARMFastISel::ARMComputeAddress(const Value *Obj, Address &Addr) { 843212793Sdim // Some boilerplate from the X86 FastISel. 844212793Sdim const User *U = NULL; 845212793Sdim unsigned Opcode = Instruction::UserOp1; 846212793Sdim if (const Instruction *I = dyn_cast<Instruction>(Obj)) { 847218893Sdim // Don't walk into other basic blocks unless the object is an alloca from 848218893Sdim // another block, otherwise it may not have a virtual register assigned. 849218893Sdim if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(Obj)) || 850218893Sdim FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB) { 851218893Sdim Opcode = I->getOpcode(); 852218893Sdim U = I; 853218893Sdim } 854212793Sdim } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) { 855212793Sdim Opcode = C->getOpcode(); 856212793Sdim U = C; 857212793Sdim } 858212793Sdim 859226890Sdim if (PointerType *Ty = dyn_cast<PointerType>(Obj->getType())) 860212793Sdim if (Ty->getAddressSpace() > 255) 861212793Sdim // Fast instruction selection doesn't support the special 862212793Sdim // address spaces. 863212793Sdim return false; 864218893Sdim 865212793Sdim switch (Opcode) { 866218893Sdim default: 867212793Sdim break; 868263509Sdim case Instruction::BitCast: 869218893Sdim // Look through bitcasts. 870218893Sdim return ARMComputeAddress(U->getOperand(0), Addr); 871263509Sdim case Instruction::IntToPtr: 872218893Sdim // Look past no-op inttoptrs. 873218893Sdim if (TLI.getValueType(U->getOperand(0)->getType()) == TLI.getPointerTy()) 874218893Sdim return ARMComputeAddress(U->getOperand(0), Addr); 875218893Sdim break; 876263509Sdim case Instruction::PtrToInt: 877218893Sdim // Look past no-op ptrtoints. 878218893Sdim if (TLI.getValueType(U->getType()) == TLI.getPointerTy()) 879218893Sdim return ARMComputeAddress(U->getOperand(0), Addr); 880218893Sdim break; 881218893Sdim case Instruction::GetElementPtr: { 882218893Sdim Address SavedAddr = Addr; 883218893Sdim int TmpOffset = Addr.Offset; 884218893Sdim 885218893Sdim // Iterate through the GEP folding the constants into offsets where 886218893Sdim // we can. 887218893Sdim gep_type_iterator GTI = gep_type_begin(U); 888218893Sdim for (User::const_op_iterator i = U->op_begin() + 1, e = U->op_end(); 889218893Sdim i != e; ++i, ++GTI) { 890218893Sdim const Value *Op = *i; 891226890Sdim if (StructType *STy = dyn_cast<StructType>(*GTI)) { 892218893Sdim const StructLayout *SL = TD.getStructLayout(STy); 893218893Sdim unsigned Idx = cast<ConstantInt>(Op)->getZExtValue(); 894218893Sdim TmpOffset += SL->getElementOffset(Idx); 895218893Sdim } else { 896218893Sdim uint64_t S = TD.getTypeAllocSize(GTI.getIndexedType()); 897221345Sdim for (;;) { 898218893Sdim if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) { 899218893Sdim // Constant-offset addressing. 900218893Sdim TmpOffset += CI->getSExtValue() * S; 901221345Sdim break; 902221345Sdim } 903263509Sdim if (canFoldAddIntoGEP(U, Op)) { 904263509Sdim // A compatible add with a constant operand. Fold the constant. 905218893Sdim ConstantInt *CI = 906221345Sdim cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1)); 907218893Sdim TmpOffset += CI->getSExtValue() * S; 908221345Sdim // Iterate on the other operand. 909221345Sdim Op = cast<AddOperator>(Op)->getOperand(0); 910221345Sdim continue; 911221345Sdim } 912221345Sdim // Unsupported 913221345Sdim goto unsupported_gep; 914221345Sdim } 915218893Sdim } 916218893Sdim } 917218893Sdim 918218893Sdim // Try to grab the base operand now. 919218893Sdim Addr.Offset = TmpOffset; 920218893Sdim if (ARMComputeAddress(U->getOperand(0), Addr)) return true; 921218893Sdim 922218893Sdim // We failed, restore everything and try the other options. 923218893Sdim Addr = SavedAddr; 924218893Sdim 925218893Sdim unsupported_gep: 926218893Sdim break; 927218893Sdim } 928212793Sdim case Instruction::Alloca: { 929218893Sdim const AllocaInst *AI = cast<AllocaInst>(Obj); 930218893Sdim DenseMap<const AllocaInst*, int>::iterator SI = 931218893Sdim FuncInfo.StaticAllocaMap.find(AI); 932218893Sdim if (SI != FuncInfo.StaticAllocaMap.end()) { 933218893Sdim Addr.BaseType = Address::FrameIndexBase; 934218893Sdim Addr.Base.FI = SI->second; 935218893Sdim return true; 936218893Sdim } 937218893Sdim break; 938212793Sdim } 939212793Sdim } 940218893Sdim 941212793Sdim // Try to get this in a register if nothing else has worked. 942218893Sdim if (Addr.Base.Reg == 0) Addr.Base.Reg = getRegForValue(Obj); 943218893Sdim return Addr.Base.Reg != 0; 944218893Sdim} 945212793Sdim 946252723Sdimvoid ARMFastISel::ARMSimplifyAddress(Address &Addr, MVT VT, bool useAM3) { 947218893Sdim bool needsLowering = false; 948252723Sdim switch (VT.SimpleTy) { 949235633Sdim default: llvm_unreachable("Unhandled load/store type!"); 950218893Sdim case MVT::i1: 951218893Sdim case MVT::i8: 952218893Sdim case MVT::i16: 953218893Sdim case MVT::i32: 954235633Sdim if (!useAM3) { 955235633Sdim // Integer loads/stores handle 12-bit offsets. 956235633Sdim needsLowering = ((Addr.Offset & 0xfff) != Addr.Offset); 957235633Sdim // Handle negative offsets. 958235633Sdim if (needsLowering && isThumb2) 959235633Sdim needsLowering = !(Subtarget->hasV6T2Ops() && Addr.Offset < 0 && 960235633Sdim Addr.Offset > -256); 961235633Sdim } else { 962235633Sdim // ARM halfword load/stores and signed byte loads use +/-imm8 offsets. 963235633Sdim needsLowering = (Addr.Offset > 255 || Addr.Offset < -255); 964235633Sdim } 965218893Sdim break; 966218893Sdim case MVT::f32: 967218893Sdim case MVT::f64: 968218893Sdim // Floating point operands handle 8-bit offsets. 969218893Sdim needsLowering = ((Addr.Offset & 0xff) != Addr.Offset); 970218893Sdim break; 971218893Sdim } 972218893Sdim 973218893Sdim // If this is a stack pointer and the offset needs to be simplified then 974218893Sdim // put the alloca address into a register, set the base type back to 975218893Sdim // register and continue. This should almost never happen. 976218893Sdim if (needsLowering && Addr.BaseType == Address::FrameIndexBase) { 977245431Sdim const TargetRegisterClass *RC = isThumb2 ? 978245431Sdim (const TargetRegisterClass*)&ARM::tGPRRegClass : 979245431Sdim (const TargetRegisterClass*)&ARM::GPRRegClass; 980218893Sdim unsigned ResultReg = createResultReg(RC); 981235633Sdim unsigned Opc = isThumb2 ? ARM::t2ADDri : ARM::ADDri; 982235633Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 983218893Sdim TII.get(Opc), ResultReg) 984218893Sdim .addFrameIndex(Addr.Base.FI) 985218893Sdim .addImm(0)); 986218893Sdim Addr.Base.Reg = ResultReg; 987218893Sdim Addr.BaseType = Address::RegBase; 988218893Sdim } 989218893Sdim 990218893Sdim // Since the offset is too large for the load/store instruction 991212793Sdim // get the reg+offset into a register. 992218893Sdim if (needsLowering) { 993221345Sdim Addr.Base.Reg = FastEmit_ri_(MVT::i32, ISD::ADD, Addr.Base.Reg, 994221345Sdim /*Op0IsKill*/false, Addr.Offset, MVT::i32); 995218893Sdim Addr.Offset = 0; 996212793Sdim } 997212793Sdim} 998212793Sdim 999252723Sdimvoid ARMFastISel::AddLoadStoreOperands(MVT VT, Address &Addr, 1000223017Sdim const MachineInstrBuilder &MIB, 1001235633Sdim unsigned Flags, bool useAM3) { 1002218893Sdim // addrmode5 output depends on the selection dag addressing dividing the 1003218893Sdim // offset by 4 that it then later multiplies. Do this here as well. 1004252723Sdim if (VT.SimpleTy == MVT::f32 || VT.SimpleTy == MVT::f64) 1005218893Sdim Addr.Offset /= 4; 1006221345Sdim 1007218893Sdim // Frame base works a bit differently. Handle it separately. 1008218893Sdim if (Addr.BaseType == Address::FrameIndexBase) { 1009218893Sdim int FI = Addr.Base.FI; 1010218893Sdim int Offset = Addr.Offset; 1011218893Sdim MachineMemOperand *MMO = 1012218893Sdim FuncInfo.MF->getMachineMemOperand( 1013218893Sdim MachinePointerInfo::getFixedStack(FI, Offset), 1014223017Sdim Flags, 1015218893Sdim MFI.getObjectSize(FI), 1016218893Sdim MFI.getObjectAlignment(FI)); 1017218893Sdim // Now add the rest of the operands. 1018218893Sdim MIB.addFrameIndex(FI); 1019212793Sdim 1020235633Sdim // ARM halfword load/stores and signed byte loads need an additional 1021235633Sdim // operand. 1022235633Sdim if (useAM3) { 1023235633Sdim signed Imm = (Addr.Offset < 0) ? (0x100 | -Addr.Offset) : Addr.Offset; 1024235633Sdim MIB.addReg(0); 1025235633Sdim MIB.addImm(Imm); 1026235633Sdim } else { 1027235633Sdim MIB.addImm(Addr.Offset); 1028235633Sdim } 1029218893Sdim MIB.addMemOperand(MMO); 1030218893Sdim } else { 1031218893Sdim // Now add the rest of the operands. 1032218893Sdim MIB.addReg(Addr.Base.Reg); 1033221345Sdim 1034235633Sdim // ARM halfword load/stores and signed byte loads need an additional 1035235633Sdim // operand. 1036235633Sdim if (useAM3) { 1037235633Sdim signed Imm = (Addr.Offset < 0) ? (0x100 | -Addr.Offset) : Addr.Offset; 1038235633Sdim MIB.addReg(0); 1039235633Sdim MIB.addImm(Imm); 1040235633Sdim } else { 1041235633Sdim MIB.addImm(Addr.Offset); 1042235633Sdim } 1043212793Sdim } 1044218893Sdim AddOptionalDefs(MIB); 1045212793Sdim} 1046212793Sdim 1047252723Sdimbool ARMFastISel::ARMEmitLoad(MVT VT, unsigned &ResultReg, Address &Addr, 1048235633Sdim unsigned Alignment, bool isZExt, bool allocReg) { 1049212793Sdim unsigned Opc; 1050235633Sdim bool useAM3 = false; 1051235633Sdim bool needVMOV = false; 1052235633Sdim const TargetRegisterClass *RC; 1053252723Sdim switch (VT.SimpleTy) { 1054218893Sdim // This is mostly going to be Neon/vector support. 1055218893Sdim default: return false; 1056235633Sdim case MVT::i1: 1057235633Sdim case MVT::i8: 1058235633Sdim if (isThumb2) { 1059235633Sdim if (Addr.Offset < 0 && Addr.Offset > -256 && Subtarget->hasV6T2Ops()) 1060235633Sdim Opc = isZExt ? ARM::t2LDRBi8 : ARM::t2LDRSBi8; 1061235633Sdim else 1062235633Sdim Opc = isZExt ? ARM::t2LDRBi12 : ARM::t2LDRSBi12; 1063235633Sdim } else { 1064235633Sdim if (isZExt) { 1065235633Sdim Opc = ARM::LDRBi12; 1066235633Sdim } else { 1067235633Sdim Opc = ARM::LDRSB; 1068235633Sdim useAM3 = true; 1069235633Sdim } 1070235633Sdim } 1071263509Sdim RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRnopcRegClass; 1072212793Sdim break; 1073235633Sdim case MVT::i16: 1074245431Sdim if (Alignment && Alignment < 2 && !Subtarget->allowsUnalignedMem()) 1075245431Sdim return false; 1076245431Sdim 1077235633Sdim if (isThumb2) { 1078235633Sdim if (Addr.Offset < 0 && Addr.Offset > -256 && Subtarget->hasV6T2Ops()) 1079235633Sdim Opc = isZExt ? ARM::t2LDRHi8 : ARM::t2LDRSHi8; 1080235633Sdim else 1081235633Sdim Opc = isZExt ? ARM::t2LDRHi12 : ARM::t2LDRSHi12; 1082235633Sdim } else { 1083235633Sdim Opc = isZExt ? ARM::LDRH : ARM::LDRSH; 1084235633Sdim useAM3 = true; 1085235633Sdim } 1086263509Sdim RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRnopcRegClass; 1087212793Sdim break; 1088212793Sdim case MVT::i32: 1089245431Sdim if (Alignment && Alignment < 4 && !Subtarget->allowsUnalignedMem()) 1090245431Sdim return false; 1091245431Sdim 1092235633Sdim if (isThumb2) { 1093235633Sdim if (Addr.Offset < 0 && Addr.Offset > -256 && Subtarget->hasV6T2Ops()) 1094235633Sdim Opc = ARM::t2LDRi8; 1095235633Sdim else 1096235633Sdim Opc = ARM::t2LDRi12; 1097235633Sdim } else { 1098235633Sdim Opc = ARM::LDRi12; 1099235633Sdim } 1100263509Sdim RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRnopcRegClass; 1101212793Sdim break; 1102218893Sdim case MVT::f32: 1103235633Sdim if (!Subtarget->hasVFP2()) return false; 1104235633Sdim // Unaligned loads need special handling. Floats require word-alignment. 1105235633Sdim if (Alignment && Alignment < 4) { 1106235633Sdim needVMOV = true; 1107235633Sdim VT = MVT::i32; 1108235633Sdim Opc = isThumb2 ? ARM::t2LDRi12 : ARM::LDRi12; 1109263509Sdim RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRnopcRegClass; 1110235633Sdim } else { 1111235633Sdim Opc = ARM::VLDRS; 1112235633Sdim RC = TLI.getRegClassFor(VT); 1113235633Sdim } 1114218893Sdim break; 1115218893Sdim case MVT::f64: 1116235633Sdim if (!Subtarget->hasVFP2()) return false; 1117235633Sdim // FIXME: Unaligned loads need special handling. Doublewords require 1118235633Sdim // word-alignment. 1119235633Sdim if (Alignment && Alignment < 4) 1120235633Sdim return false; 1121235633Sdim 1122218893Sdim Opc = ARM::VLDRD; 1123218893Sdim RC = TLI.getRegClassFor(VT); 1124218893Sdim break; 1125212793Sdim } 1126218893Sdim // Simplify this down to something we can handle. 1127235633Sdim ARMSimplifyAddress(Addr, VT, useAM3); 1128218893Sdim 1129218893Sdim // Create the base instruction, then add the operands. 1130235633Sdim if (allocReg) 1131235633Sdim ResultReg = createResultReg(RC); 1132235633Sdim assert (ResultReg > 255 && "Expected an allocated virtual register."); 1133218893Sdim MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 1134218893Sdim TII.get(Opc), ResultReg); 1135235633Sdim AddLoadStoreOperands(VT, Addr, MIB, MachineMemOperand::MOLoad, useAM3); 1136235633Sdim 1137235633Sdim // If we had an unaligned load of a float we've converted it to an regular 1138235633Sdim // load. Now we must move from the GRP to the FP register. 1139235633Sdim if (needVMOV) { 1140235633Sdim unsigned MoveReg = createResultReg(TLI.getRegClassFor(MVT::f32)); 1141235633Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 1142235633Sdim TII.get(ARM::VMOVSR), MoveReg) 1143235633Sdim .addReg(ResultReg)); 1144235633Sdim ResultReg = MoveReg; 1145235633Sdim } 1146212793Sdim return true; 1147212793Sdim} 1148212793Sdim 1149218893Sdimbool ARMFastISel::SelectLoad(const Instruction *I) { 1150226890Sdim // Atomic loads need special handling. 1151226890Sdim if (cast<LoadInst>(I)->isAtomic()) 1152226890Sdim return false; 1153226890Sdim 1154218893Sdim // Verify we have a legal type before going any further. 1155218893Sdim MVT VT; 1156218893Sdim if (!isLoadTypeLegal(I->getType(), VT)) 1157218893Sdim return false; 1158212793Sdim 1159218893Sdim // See if we can handle this address. 1160218893Sdim Address Addr; 1161218893Sdim if (!ARMComputeAddress(I->getOperand(0), Addr)) return false; 1162212793Sdim 1163218893Sdim unsigned ResultReg; 1164235633Sdim if (!ARMEmitLoad(VT, ResultReg, Addr, cast<LoadInst>(I)->getAlignment())) 1165235633Sdim return false; 1166218893Sdim UpdateValueMap(I, ResultReg); 1167218893Sdim return true; 1168212793Sdim} 1169212793Sdim 1170252723Sdimbool ARMFastISel::ARMEmitStore(MVT VT, unsigned SrcReg, Address &Addr, 1171235633Sdim unsigned Alignment) { 1172212793Sdim unsigned StrOpc; 1173235633Sdim bool useAM3 = false; 1174252723Sdim switch (VT.SimpleTy) { 1175218893Sdim // This is mostly going to be Neon/vector support. 1176212793Sdim default: return false; 1177218893Sdim case MVT::i1: { 1178245431Sdim unsigned Res = createResultReg(isThumb2 ? 1179245431Sdim (const TargetRegisterClass*)&ARM::tGPRRegClass : 1180245431Sdim (const TargetRegisterClass*)&ARM::GPRRegClass); 1181235633Sdim unsigned Opc = isThumb2 ? ARM::t2ANDri : ARM::ANDri; 1182263509Sdim SrcReg = constrainOperandRegClass(TII.get(Opc), SrcReg, 1); 1183218893Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 1184218893Sdim TII.get(Opc), Res) 1185218893Sdim .addReg(SrcReg).addImm(1)); 1186218893Sdim SrcReg = Res; 1187218893Sdim } // Fallthrough here. 1188218893Sdim case MVT::i8: 1189235633Sdim if (isThumb2) { 1190235633Sdim if (Addr.Offset < 0 && Addr.Offset > -256 && Subtarget->hasV6T2Ops()) 1191235633Sdim StrOpc = ARM::t2STRBi8; 1192235633Sdim else 1193235633Sdim StrOpc = ARM::t2STRBi12; 1194235633Sdim } else { 1195235633Sdim StrOpc = ARM::STRBi12; 1196235633Sdim } 1197218893Sdim break; 1198218893Sdim case MVT::i16: 1199245431Sdim if (Alignment && Alignment < 2 && !Subtarget->allowsUnalignedMem()) 1200245431Sdim return false; 1201245431Sdim 1202235633Sdim if (isThumb2) { 1203235633Sdim if (Addr.Offset < 0 && Addr.Offset > -256 && Subtarget->hasV6T2Ops()) 1204235633Sdim StrOpc = ARM::t2STRHi8; 1205235633Sdim else 1206235633Sdim StrOpc = ARM::t2STRHi12; 1207235633Sdim } else { 1208235633Sdim StrOpc = ARM::STRH; 1209235633Sdim useAM3 = true; 1210235633Sdim } 1211218893Sdim break; 1212218893Sdim case MVT::i32: 1213245431Sdim if (Alignment && Alignment < 4 && !Subtarget->allowsUnalignedMem()) 1214245431Sdim return false; 1215245431Sdim 1216235633Sdim if (isThumb2) { 1217235633Sdim if (Addr.Offset < 0 && Addr.Offset > -256 && Subtarget->hasV6T2Ops()) 1218235633Sdim StrOpc = ARM::t2STRi8; 1219235633Sdim else 1220235633Sdim StrOpc = ARM::t2STRi12; 1221235633Sdim } else { 1222235633Sdim StrOpc = ARM::STRi12; 1223235633Sdim } 1224218893Sdim break; 1225212793Sdim case MVT::f32: 1226212793Sdim if (!Subtarget->hasVFP2()) return false; 1227235633Sdim // Unaligned stores need special handling. Floats require word-alignment. 1228235633Sdim if (Alignment && Alignment < 4) { 1229235633Sdim unsigned MoveReg = createResultReg(TLI.getRegClassFor(MVT::i32)); 1230235633Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 1231235633Sdim TII.get(ARM::VMOVRS), MoveReg) 1232235633Sdim .addReg(SrcReg)); 1233235633Sdim SrcReg = MoveReg; 1234235633Sdim VT = MVT::i32; 1235235633Sdim StrOpc = isThumb2 ? ARM::t2STRi12 : ARM::STRi12; 1236235633Sdim } else { 1237235633Sdim StrOpc = ARM::VSTRS; 1238235633Sdim } 1239212793Sdim break; 1240212793Sdim case MVT::f64: 1241212793Sdim if (!Subtarget->hasVFP2()) return false; 1242235633Sdim // FIXME: Unaligned stores need special handling. Doublewords require 1243235633Sdim // word-alignment. 1244235633Sdim if (Alignment && Alignment < 4) 1245235633Sdim return false; 1246235633Sdim 1247212793Sdim StrOpc = ARM::VSTRD; 1248212793Sdim break; 1249212793Sdim } 1250218893Sdim // Simplify this down to something we can handle. 1251235633Sdim ARMSimplifyAddress(Addr, VT, useAM3); 1252218893Sdim 1253218893Sdim // Create the base instruction, then add the operands. 1254263509Sdim SrcReg = constrainOperandRegClass(TII.get(StrOpc), SrcReg, 0); 1255218893Sdim MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 1256218893Sdim TII.get(StrOpc)) 1257235633Sdim .addReg(SrcReg); 1258235633Sdim AddLoadStoreOperands(VT, Addr, MIB, MachineMemOperand::MOStore, useAM3); 1259212793Sdim return true; 1260212793Sdim} 1261212793Sdim 1262218893Sdimbool ARMFastISel::SelectStore(const Instruction *I) { 1263212793Sdim Value *Op0 = I->getOperand(0); 1264212793Sdim unsigned SrcReg = 0; 1265212793Sdim 1266226890Sdim // Atomic stores need special handling. 1267226890Sdim if (cast<StoreInst>(I)->isAtomic()) 1268226890Sdim return false; 1269226890Sdim 1270218893Sdim // Verify we have a legal type before going any further. 1271218893Sdim MVT VT; 1272212793Sdim if (!isLoadTypeLegal(I->getOperand(0)->getType(), VT)) 1273212793Sdim return false; 1274212793Sdim 1275212793Sdim // Get the value to be stored into a register. 1276212793Sdim SrcReg = getRegForValue(Op0); 1277218893Sdim if (SrcReg == 0) return false; 1278218893Sdim 1279218893Sdim // See if we can handle this address. 1280218893Sdim Address Addr; 1281218893Sdim if (!ARMComputeAddress(I->getOperand(1), Addr)) 1282212793Sdim return false; 1283212793Sdim 1284235633Sdim if (!ARMEmitStore(VT, SrcReg, Addr, cast<StoreInst>(I)->getAlignment())) 1285235633Sdim return false; 1286212793Sdim return true; 1287212793Sdim} 1288212793Sdim 1289218893Sdimstatic ARMCC::CondCodes getComparePred(CmpInst::Predicate Pred) { 1290218893Sdim switch (Pred) { 1291218893Sdim // Needs two compares... 1292218893Sdim case CmpInst::FCMP_ONE: 1293218893Sdim case CmpInst::FCMP_UEQ: 1294218893Sdim default: 1295218893Sdim // AL is our "false" for now. The other two need more compares. 1296218893Sdim return ARMCC::AL; 1297218893Sdim case CmpInst::ICMP_EQ: 1298218893Sdim case CmpInst::FCMP_OEQ: 1299218893Sdim return ARMCC::EQ; 1300218893Sdim case CmpInst::ICMP_SGT: 1301218893Sdim case CmpInst::FCMP_OGT: 1302218893Sdim return ARMCC::GT; 1303218893Sdim case CmpInst::ICMP_SGE: 1304218893Sdim case CmpInst::FCMP_OGE: 1305218893Sdim return ARMCC::GE; 1306218893Sdim case CmpInst::ICMP_UGT: 1307218893Sdim case CmpInst::FCMP_UGT: 1308218893Sdim return ARMCC::HI; 1309218893Sdim case CmpInst::FCMP_OLT: 1310218893Sdim return ARMCC::MI; 1311218893Sdim case CmpInst::ICMP_ULE: 1312218893Sdim case CmpInst::FCMP_OLE: 1313218893Sdim return ARMCC::LS; 1314218893Sdim case CmpInst::FCMP_ORD: 1315218893Sdim return ARMCC::VC; 1316218893Sdim case CmpInst::FCMP_UNO: 1317218893Sdim return ARMCC::VS; 1318218893Sdim case CmpInst::FCMP_UGE: 1319218893Sdim return ARMCC::PL; 1320218893Sdim case CmpInst::ICMP_SLT: 1321218893Sdim case CmpInst::FCMP_ULT: 1322218893Sdim return ARMCC::LT; 1323218893Sdim case CmpInst::ICMP_SLE: 1324218893Sdim case CmpInst::FCMP_ULE: 1325218893Sdim return ARMCC::LE; 1326218893Sdim case CmpInst::FCMP_UNE: 1327218893Sdim case CmpInst::ICMP_NE: 1328218893Sdim return ARMCC::NE; 1329218893Sdim case CmpInst::ICMP_UGE: 1330218893Sdim return ARMCC::HS; 1331218893Sdim case CmpInst::ICMP_ULT: 1332218893Sdim return ARMCC::LO; 1333218893Sdim } 1334218893Sdim} 1335218893Sdim 1336218893Sdimbool ARMFastISel::SelectBranch(const Instruction *I) { 1337212793Sdim const BranchInst *BI = cast<BranchInst>(I); 1338212793Sdim MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)]; 1339212793Sdim MachineBasicBlock *FBB = FuncInfo.MBBMap[BI->getSuccessor(1)]; 1340218893Sdim 1341212793Sdim // Simple branch support. 1342218893Sdim 1343218893Sdim // If we can, avoid recomputing the compare - redoing it could lead to wonky 1344218893Sdim // behavior. 1345218893Sdim if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) { 1346235633Sdim if (CI->hasOneUse() && (CI->getParent() == I->getParent())) { 1347218893Sdim 1348218893Sdim // Get the compare predicate. 1349221345Sdim // Try to take advantage of fallthrough opportunities. 1350221345Sdim CmpInst::Predicate Predicate = CI->getPredicate(); 1351221345Sdim if (FuncInfo.MBB->isLayoutSuccessor(TBB)) { 1352221345Sdim std::swap(TBB, FBB); 1353221345Sdim Predicate = CmpInst::getInversePredicate(Predicate); 1354221345Sdim } 1355218893Sdim 1356221345Sdim ARMCC::CondCodes ARMPred = getComparePred(Predicate); 1357221345Sdim 1358218893Sdim // We may not handle every CC for now. 1359218893Sdim if (ARMPred == ARMCC::AL) return false; 1360218893Sdim 1361235633Sdim // Emit the compare. 1362235633Sdim if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned())) 1363235633Sdim return false; 1364218893Sdim 1365235633Sdim unsigned BrOpc = isThumb2 ? ARM::t2Bcc : ARM::Bcc; 1366218893Sdim BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(BrOpc)) 1367218893Sdim .addMBB(TBB).addImm(ARMPred).addReg(ARM::CPSR); 1368218893Sdim FastEmitBranch(FBB, DL); 1369218893Sdim FuncInfo.MBB->addSuccessor(TBB); 1370218893Sdim return true; 1371218893Sdim } 1372221345Sdim } else if (TruncInst *TI = dyn_cast<TruncInst>(BI->getCondition())) { 1373221345Sdim MVT SourceVT; 1374221345Sdim if (TI->hasOneUse() && TI->getParent() == I->getParent() && 1375223017Sdim (isLoadTypeLegal(TI->getOperand(0)->getType(), SourceVT))) { 1376235633Sdim unsigned TstOpc = isThumb2 ? ARM::t2TSTri : ARM::TSTri; 1377221345Sdim unsigned OpReg = getRegForValue(TI->getOperand(0)); 1378263509Sdim OpReg = constrainOperandRegClass(TII.get(TstOpc), OpReg, 0); 1379221345Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 1380221345Sdim TII.get(TstOpc)) 1381221345Sdim .addReg(OpReg).addImm(1)); 1382221345Sdim 1383221345Sdim unsigned CCMode = ARMCC::NE; 1384221345Sdim if (FuncInfo.MBB->isLayoutSuccessor(TBB)) { 1385221345Sdim std::swap(TBB, FBB); 1386221345Sdim CCMode = ARMCC::EQ; 1387221345Sdim } 1388221345Sdim 1389235633Sdim unsigned BrOpc = isThumb2 ? ARM::t2Bcc : ARM::Bcc; 1390221345Sdim BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(BrOpc)) 1391221345Sdim .addMBB(TBB).addImm(CCMode).addReg(ARM::CPSR); 1392221345Sdim 1393221345Sdim FastEmitBranch(FBB, DL); 1394221345Sdim FuncInfo.MBB->addSuccessor(TBB); 1395221345Sdim return true; 1396221345Sdim } 1397235633Sdim } else if (const ConstantInt *CI = 1398235633Sdim dyn_cast<ConstantInt>(BI->getCondition())) { 1399235633Sdim uint64_t Imm = CI->getZExtValue(); 1400235633Sdim MachineBasicBlock *Target = (Imm == 0) ? FBB : TBB; 1401235633Sdim FastEmitBranch(Target, DL); 1402235633Sdim return true; 1403218893Sdim } 1404218893Sdim 1405218893Sdim unsigned CmpReg = getRegForValue(BI->getCondition()); 1406218893Sdim if (CmpReg == 0) return false; 1407218893Sdim 1408221345Sdim // We've been divorced from our compare! Our block was split, and 1409221345Sdim // now our compare lives in a predecessor block. We musn't 1410221345Sdim // re-compare here, as the children of the compare aren't guaranteed 1411221345Sdim // live across the block boundary (we *could* check for this). 1412221345Sdim // Regardless, the compare has been done in the predecessor block, 1413221345Sdim // and it left a value for us in a virtual register. Ergo, we test 1414221345Sdim // the one-bit value left in the virtual register. 1415235633Sdim unsigned TstOpc = isThumb2 ? ARM::t2TSTri : ARM::TSTri; 1416263509Sdim CmpReg = constrainOperandRegClass(TII.get(TstOpc), CmpReg, 0); 1417221345Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TstOpc)) 1418221345Sdim .addReg(CmpReg).addImm(1)); 1419218893Sdim 1420221345Sdim unsigned CCMode = ARMCC::NE; 1421221345Sdim if (FuncInfo.MBB->isLayoutSuccessor(TBB)) { 1422221345Sdim std::swap(TBB, FBB); 1423221345Sdim CCMode = ARMCC::EQ; 1424221345Sdim } 1425221345Sdim 1426235633Sdim unsigned BrOpc = isThumb2 ? ARM::t2Bcc : ARM::Bcc; 1427212793Sdim BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(BrOpc)) 1428221345Sdim .addMBB(TBB).addImm(CCMode).addReg(ARM::CPSR); 1429212793Sdim FastEmitBranch(FBB, DL); 1430212793Sdim FuncInfo.MBB->addSuccessor(TBB); 1431212793Sdim return true; 1432212793Sdim} 1433212793Sdim 1434235633Sdimbool ARMFastISel::SelectIndirectBr(const Instruction *I) { 1435235633Sdim unsigned AddrReg = getRegForValue(I->getOperand(0)); 1436235633Sdim if (AddrReg == 0) return false; 1437218893Sdim 1438235633Sdim unsigned Opc = isThumb2 ? ARM::tBRIND : ARM::BX; 1439235633Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc)) 1440235633Sdim .addReg(AddrReg)); 1441245431Sdim 1442245431Sdim const IndirectBrInst *IB = cast<IndirectBrInst>(I); 1443245431Sdim for (unsigned i = 0, e = IB->getNumSuccessors(); i != e; ++i) 1444245431Sdim FuncInfo.MBB->addSuccessor(FuncInfo.MBBMap[IB->getSuccessor(i)]); 1445245431Sdim 1446245431Sdim return true; 1447235633Sdim} 1448218893Sdim 1449235633Sdimbool ARMFastISel::ARMEmitCmp(const Value *Src1Value, const Value *Src2Value, 1450235633Sdim bool isZExt) { 1451235633Sdim Type *Ty = Src1Value->getType(); 1452252723Sdim EVT SrcEVT = TLI.getValueType(Ty, true); 1453252723Sdim if (!SrcEVT.isSimple()) return false; 1454252723Sdim MVT SrcVT = SrcEVT.getSimpleVT(); 1455235633Sdim 1456235633Sdim bool isFloat = (Ty->isFloatTy() || Ty->isDoubleTy()); 1457218893Sdim if (isFloat && !Subtarget->hasVFP2()) 1458218893Sdim return false; 1459218893Sdim 1460235633Sdim // Check to see if the 2nd operand is a constant that we can encode directly 1461235633Sdim // in the compare. 1462235633Sdim int Imm = 0; 1463235633Sdim bool UseImm = false; 1464235633Sdim bool isNegativeImm = false; 1465235633Sdim // FIXME: At -O0 we don't have anything that canonicalizes operand order. 1466235633Sdim // Thus, Src1Value may be a ConstantInt, but we're missing it. 1467235633Sdim if (const ConstantInt *ConstInt = dyn_cast<ConstantInt>(Src2Value)) { 1468235633Sdim if (SrcVT == MVT::i32 || SrcVT == MVT::i16 || SrcVT == MVT::i8 || 1469235633Sdim SrcVT == MVT::i1) { 1470235633Sdim const APInt &CIVal = ConstInt->getValue(); 1471235633Sdim Imm = (isZExt) ? (int)CIVal.getZExtValue() : (int)CIVal.getSExtValue(); 1472235633Sdim // For INT_MIN/LONG_MIN (i.e., 0x80000000) we need to use a cmp, rather 1473235633Sdim // then a cmn, because there is no way to represent 2147483648 as a 1474235633Sdim // signed 32-bit int. 1475235633Sdim if (Imm < 0 && Imm != (int)0x80000000) { 1476235633Sdim isNegativeImm = true; 1477235633Sdim Imm = -Imm; 1478235633Sdim } 1479235633Sdim UseImm = isThumb2 ? (ARM_AM::getT2SOImmVal(Imm) != -1) : 1480235633Sdim (ARM_AM::getSOImmVal(Imm) != -1); 1481235633Sdim } 1482235633Sdim } else if (const ConstantFP *ConstFP = dyn_cast<ConstantFP>(Src2Value)) { 1483235633Sdim if (SrcVT == MVT::f32 || SrcVT == MVT::f64) 1484235633Sdim if (ConstFP->isZero() && !ConstFP->isNegative()) 1485235633Sdim UseImm = true; 1486235633Sdim } 1487235633Sdim 1488218893Sdim unsigned CmpOpc; 1489235633Sdim bool isICmp = true; 1490235633Sdim bool needsExt = false; 1491252723Sdim switch (SrcVT.SimpleTy) { 1492218893Sdim default: return false; 1493218893Sdim // TODO: Verify compares. 1494218893Sdim case MVT::f32: 1495235633Sdim isICmp = false; 1496235633Sdim CmpOpc = UseImm ? ARM::VCMPEZS : ARM::VCMPES; 1497218893Sdim break; 1498218893Sdim case MVT::f64: 1499235633Sdim isICmp = false; 1500235633Sdim CmpOpc = UseImm ? ARM::VCMPEZD : ARM::VCMPED; 1501218893Sdim break; 1502235633Sdim case MVT::i1: 1503235633Sdim case MVT::i8: 1504235633Sdim case MVT::i16: 1505235633Sdim needsExt = true; 1506235633Sdim // Intentional fall-through. 1507218893Sdim case MVT::i32: 1508235633Sdim if (isThumb2) { 1509235633Sdim if (!UseImm) 1510235633Sdim CmpOpc = ARM::t2CMPrr; 1511235633Sdim else 1512245431Sdim CmpOpc = isNegativeImm ? ARM::t2CMNri : ARM::t2CMPri; 1513235633Sdim } else { 1514235633Sdim if (!UseImm) 1515235633Sdim CmpOpc = ARM::CMPrr; 1516235633Sdim else 1517245431Sdim CmpOpc = isNegativeImm ? ARM::CMNri : ARM::CMPri; 1518235633Sdim } 1519218893Sdim break; 1520218893Sdim } 1521218893Sdim 1522235633Sdim unsigned SrcReg1 = getRegForValue(Src1Value); 1523235633Sdim if (SrcReg1 == 0) return false; 1524218893Sdim 1525235633Sdim unsigned SrcReg2 = 0; 1526235633Sdim if (!UseImm) { 1527235633Sdim SrcReg2 = getRegForValue(Src2Value); 1528235633Sdim if (SrcReg2 == 0) return false; 1529235633Sdim } 1530218893Sdim 1531235633Sdim // We have i1, i8, or i16, we need to either zero extend or sign extend. 1532235633Sdim if (needsExt) { 1533235633Sdim SrcReg1 = ARMEmitIntExt(SrcVT, SrcReg1, MVT::i32, isZExt); 1534235633Sdim if (SrcReg1 == 0) return false; 1535235633Sdim if (!UseImm) { 1536235633Sdim SrcReg2 = ARMEmitIntExt(SrcVT, SrcReg2, MVT::i32, isZExt); 1537235633Sdim if (SrcReg2 == 0) return false; 1538235633Sdim } 1539235633Sdim } 1540218893Sdim 1541263509Sdim const MCInstrDesc &II = TII.get(CmpOpc); 1542263509Sdim SrcReg1 = constrainOperandRegClass(II, SrcReg1, 0); 1543235633Sdim if (!UseImm) { 1544263509Sdim SrcReg2 = constrainOperandRegClass(II, SrcReg2, 1); 1545263509Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) 1546235633Sdim .addReg(SrcReg1).addReg(SrcReg2)); 1547235633Sdim } else { 1548235633Sdim MachineInstrBuilder MIB; 1549263509Sdim MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) 1550235633Sdim .addReg(SrcReg1); 1551218893Sdim 1552235633Sdim // Only add immediate for icmp as the immediate for fcmp is an implicit 0.0. 1553235633Sdim if (isICmp) 1554235633Sdim MIB.addImm(Imm); 1555235633Sdim AddOptionalDefs(MIB); 1556235633Sdim } 1557218893Sdim 1558218893Sdim // For floating point we need to move the result to a comparison register 1559218893Sdim // that we can then use for branches. 1560235633Sdim if (Ty->isFloatTy() || Ty->isDoubleTy()) 1561218893Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 1562218893Sdim TII.get(ARM::FMSTAT))); 1563235633Sdim return true; 1564235633Sdim} 1565218893Sdim 1566235633Sdimbool ARMFastISel::SelectCmp(const Instruction *I) { 1567235633Sdim const CmpInst *CI = cast<CmpInst>(I); 1568235633Sdim 1569235633Sdim // Get the compare predicate. 1570235633Sdim ARMCC::CondCodes ARMPred = getComparePred(CI->getPredicate()); 1571235633Sdim 1572235633Sdim // We may not handle every CC for now. 1573235633Sdim if (ARMPred == ARMCC::AL) return false; 1574235633Sdim 1575235633Sdim // Emit the compare. 1576235633Sdim if (!ARMEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned())) 1577235633Sdim return false; 1578235633Sdim 1579218893Sdim // Now set a register based on the comparison. Explicitly set the predicates 1580218893Sdim // here. 1581235633Sdim unsigned MovCCOpc = isThumb2 ? ARM::t2MOVCCi : ARM::MOVCCi; 1582245431Sdim const TargetRegisterClass *RC = isThumb2 ? 1583245431Sdim (const TargetRegisterClass*)&ARM::rGPRRegClass : 1584245431Sdim (const TargetRegisterClass*)&ARM::GPRRegClass; 1585218893Sdim unsigned DestReg = createResultReg(RC); 1586235633Sdim Constant *Zero = ConstantInt::get(Type::getInt32Ty(*Context), 0); 1587218893Sdim unsigned ZeroReg = TargetMaterializeConstant(Zero); 1588235633Sdim // ARMEmitCmp emits a FMSTAT when necessary, so it's always safe to use CPSR. 1589218893Sdim BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(MovCCOpc), DestReg) 1590218893Sdim .addReg(ZeroReg).addImm(1) 1591235633Sdim .addImm(ARMPred).addReg(ARM::CPSR); 1592218893Sdim 1593218893Sdim UpdateValueMap(I, DestReg); 1594218893Sdim return true; 1595218893Sdim} 1596218893Sdim 1597218893Sdimbool ARMFastISel::SelectFPExt(const Instruction *I) { 1598218893Sdim // Make sure we have VFP and that we're extending float to double. 1599218893Sdim if (!Subtarget->hasVFP2()) return false; 1600218893Sdim 1601218893Sdim Value *V = I->getOperand(0); 1602218893Sdim if (!I->getType()->isDoubleTy() || 1603218893Sdim !V->getType()->isFloatTy()) return false; 1604218893Sdim 1605218893Sdim unsigned Op = getRegForValue(V); 1606218893Sdim if (Op == 0) return false; 1607218893Sdim 1608245431Sdim unsigned Result = createResultReg(&ARM::DPRRegClass); 1609218893Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 1610218893Sdim TII.get(ARM::VCVTDS), Result) 1611218893Sdim .addReg(Op)); 1612218893Sdim UpdateValueMap(I, Result); 1613218893Sdim return true; 1614218893Sdim} 1615218893Sdim 1616218893Sdimbool ARMFastISel::SelectFPTrunc(const Instruction *I) { 1617218893Sdim // Make sure we have VFP and that we're truncating double to float. 1618218893Sdim if (!Subtarget->hasVFP2()) return false; 1619218893Sdim 1620218893Sdim Value *V = I->getOperand(0); 1621218893Sdim if (!(I->getType()->isFloatTy() && 1622218893Sdim V->getType()->isDoubleTy())) return false; 1623218893Sdim 1624218893Sdim unsigned Op = getRegForValue(V); 1625218893Sdim if (Op == 0) return false; 1626218893Sdim 1627245431Sdim unsigned Result = createResultReg(&ARM::SPRRegClass); 1628218893Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 1629218893Sdim TII.get(ARM::VCVTSD), Result) 1630218893Sdim .addReg(Op)); 1631218893Sdim UpdateValueMap(I, Result); 1632218893Sdim return true; 1633218893Sdim} 1634218893Sdim 1635235633Sdimbool ARMFastISel::SelectIToFP(const Instruction *I, bool isSigned) { 1636218893Sdim // Make sure we have VFP. 1637218893Sdim if (!Subtarget->hasVFP2()) return false; 1638218893Sdim 1639218893Sdim MVT DstVT; 1640226890Sdim Type *Ty = I->getType(); 1641218893Sdim if (!isTypeLegal(Ty, DstVT)) 1642218893Sdim return false; 1643218893Sdim 1644235633Sdim Value *Src = I->getOperand(0); 1645252723Sdim EVT SrcEVT = TLI.getValueType(Src->getType(), true); 1646252723Sdim if (!SrcEVT.isSimple()) 1647252723Sdim return false; 1648252723Sdim MVT SrcVT = SrcEVT.getSimpleVT(); 1649235633Sdim if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8) 1650223017Sdim return false; 1651223017Sdim 1652235633Sdim unsigned SrcReg = getRegForValue(Src); 1653235633Sdim if (SrcReg == 0) return false; 1654218893Sdim 1655235633Sdim // Handle sign-extension. 1656235633Sdim if (SrcVT == MVT::i16 || SrcVT == MVT::i8) { 1657252723Sdim SrcReg = ARMEmitIntExt(SrcVT, SrcReg, MVT::i32, 1658235633Sdim /*isZExt*/!isSigned); 1659235633Sdim if (SrcReg == 0) return false; 1660235633Sdim } 1661235633Sdim 1662218893Sdim // The conversion routine works on fp-reg to fp-reg and the operand above 1663218893Sdim // was an integer, move it to the fp registers if possible. 1664235633Sdim unsigned FP = ARMMoveToFPReg(MVT::f32, SrcReg); 1665218893Sdim if (FP == 0) return false; 1666218893Sdim 1667218893Sdim unsigned Opc; 1668235633Sdim if (Ty->isFloatTy()) Opc = isSigned ? ARM::VSITOS : ARM::VUITOS; 1669235633Sdim else if (Ty->isDoubleTy()) Opc = isSigned ? ARM::VSITOD : ARM::VUITOD; 1670226890Sdim else return false; 1671218893Sdim 1672218893Sdim unsigned ResultReg = createResultReg(TLI.getRegClassFor(DstVT)); 1673218893Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), 1674218893Sdim ResultReg) 1675218893Sdim .addReg(FP)); 1676218893Sdim UpdateValueMap(I, ResultReg); 1677218893Sdim return true; 1678218893Sdim} 1679218893Sdim 1680235633Sdimbool ARMFastISel::SelectFPToI(const Instruction *I, bool isSigned) { 1681218893Sdim // Make sure we have VFP. 1682218893Sdim if (!Subtarget->hasVFP2()) return false; 1683218893Sdim 1684218893Sdim MVT DstVT; 1685226890Sdim Type *RetTy = I->getType(); 1686218893Sdim if (!isTypeLegal(RetTy, DstVT)) 1687218893Sdim return false; 1688218893Sdim 1689218893Sdim unsigned Op = getRegForValue(I->getOperand(0)); 1690218893Sdim if (Op == 0) return false; 1691218893Sdim 1692218893Sdim unsigned Opc; 1693226890Sdim Type *OpTy = I->getOperand(0)->getType(); 1694235633Sdim if (OpTy->isFloatTy()) Opc = isSigned ? ARM::VTOSIZS : ARM::VTOUIZS; 1695235633Sdim else if (OpTy->isDoubleTy()) Opc = isSigned ? ARM::VTOSIZD : ARM::VTOUIZD; 1696226890Sdim else return false; 1697218893Sdim 1698235633Sdim // f64->s32/u32 or f32->s32/u32 both need an intermediate f32 reg. 1699218893Sdim unsigned ResultReg = createResultReg(TLI.getRegClassFor(MVT::f32)); 1700218893Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), 1701218893Sdim ResultReg) 1702218893Sdim .addReg(Op)); 1703218893Sdim 1704218893Sdim // This result needs to be in an integer register, but the conversion only 1705218893Sdim // takes place in fp-regs. 1706218893Sdim unsigned IntReg = ARMMoveToIntReg(DstVT, ResultReg); 1707218893Sdim if (IntReg == 0) return false; 1708218893Sdim 1709218893Sdim UpdateValueMap(I, IntReg); 1710218893Sdim return true; 1711218893Sdim} 1712218893Sdim 1713218893Sdimbool ARMFastISel::SelectSelect(const Instruction *I) { 1714218893Sdim MVT VT; 1715218893Sdim if (!isTypeLegal(I->getType(), VT)) 1716218893Sdim return false; 1717218893Sdim 1718218893Sdim // Things need to be register sized for register moves. 1719218893Sdim if (VT != MVT::i32) return false; 1720218893Sdim 1721218893Sdim unsigned CondReg = getRegForValue(I->getOperand(0)); 1722218893Sdim if (CondReg == 0) return false; 1723218893Sdim unsigned Op1Reg = getRegForValue(I->getOperand(1)); 1724218893Sdim if (Op1Reg == 0) return false; 1725218893Sdim 1726235633Sdim // Check to see if we can use an immediate in the conditional move. 1727235633Sdim int Imm = 0; 1728235633Sdim bool UseImm = false; 1729235633Sdim bool isNegativeImm = false; 1730235633Sdim if (const ConstantInt *ConstInt = dyn_cast<ConstantInt>(I->getOperand(2))) { 1731235633Sdim assert (VT == MVT::i32 && "Expecting an i32."); 1732235633Sdim Imm = (int)ConstInt->getValue().getZExtValue(); 1733235633Sdim if (Imm < 0) { 1734235633Sdim isNegativeImm = true; 1735235633Sdim Imm = ~Imm; 1736235633Sdim } 1737235633Sdim UseImm = isThumb2 ? (ARM_AM::getT2SOImmVal(Imm) != -1) : 1738235633Sdim (ARM_AM::getSOImmVal(Imm) != -1); 1739235633Sdim } 1740235633Sdim 1741235633Sdim unsigned Op2Reg = 0; 1742235633Sdim if (!UseImm) { 1743235633Sdim Op2Reg = getRegForValue(I->getOperand(2)); 1744235633Sdim if (Op2Reg == 0) return false; 1745235633Sdim } 1746235633Sdim 1747235633Sdim unsigned CmpOpc = isThumb2 ? ARM::t2CMPri : ARM::CMPri; 1748263509Sdim CondReg = constrainOperandRegClass(TII.get(CmpOpc), CondReg, 0); 1749218893Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc)) 1750235633Sdim .addReg(CondReg).addImm(0)); 1751235633Sdim 1752235633Sdim unsigned MovCCOpc; 1753252723Sdim const TargetRegisterClass *RC; 1754235633Sdim if (!UseImm) { 1755252723Sdim RC = isThumb2 ? &ARM::tGPRRegClass : &ARM::GPRRegClass; 1756235633Sdim MovCCOpc = isThumb2 ? ARM::t2MOVCCr : ARM::MOVCCr; 1757235633Sdim } else { 1758252723Sdim RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRRegClass; 1759252723Sdim if (!isNegativeImm) 1760235633Sdim MovCCOpc = isThumb2 ? ARM::t2MOVCCi : ARM::MOVCCi; 1761252723Sdim else 1762235633Sdim MovCCOpc = isThumb2 ? ARM::t2MVNCCi : ARM::MVNCCi; 1763235633Sdim } 1764218893Sdim unsigned ResultReg = createResultReg(RC); 1765263509Sdim if (!UseImm) { 1766263509Sdim Op2Reg = constrainOperandRegClass(TII.get(MovCCOpc), Op2Reg, 1); 1767263509Sdim Op1Reg = constrainOperandRegClass(TII.get(MovCCOpc), Op1Reg, 2); 1768235633Sdim BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(MovCCOpc), ResultReg) 1769235633Sdim .addReg(Op2Reg).addReg(Op1Reg).addImm(ARMCC::NE).addReg(ARM::CPSR); 1770263509Sdim } else { 1771263509Sdim Op1Reg = constrainOperandRegClass(TII.get(MovCCOpc), Op1Reg, 1); 1772235633Sdim BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(MovCCOpc), ResultReg) 1773235633Sdim .addReg(Op1Reg).addImm(Imm).addImm(ARMCC::EQ).addReg(ARM::CPSR); 1774263509Sdim } 1775218893Sdim UpdateValueMap(I, ResultReg); 1776218893Sdim return true; 1777218893Sdim} 1778218893Sdim 1779235633Sdimbool ARMFastISel::SelectDiv(const Instruction *I, bool isSigned) { 1780218893Sdim MVT VT; 1781226890Sdim Type *Ty = I->getType(); 1782218893Sdim if (!isTypeLegal(Ty, VT)) 1783218893Sdim return false; 1784218893Sdim 1785218893Sdim // If we have integer div support we should have selected this automagically. 1786218893Sdim // In case we have a real miss go ahead and return false and we'll pick 1787218893Sdim // it up later. 1788218893Sdim if (Subtarget->hasDivide()) return false; 1789218893Sdim 1790218893Sdim // Otherwise emit a libcall. 1791218893Sdim RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 1792218893Sdim if (VT == MVT::i8) 1793235633Sdim LC = isSigned ? RTLIB::SDIV_I8 : RTLIB::UDIV_I8; 1794218893Sdim else if (VT == MVT::i16) 1795235633Sdim LC = isSigned ? RTLIB::SDIV_I16 : RTLIB::UDIV_I16; 1796218893Sdim else if (VT == MVT::i32) 1797235633Sdim LC = isSigned ? RTLIB::SDIV_I32 : RTLIB::UDIV_I32; 1798218893Sdim else if (VT == MVT::i64) 1799235633Sdim LC = isSigned ? RTLIB::SDIV_I64 : RTLIB::UDIV_I64; 1800218893Sdim else if (VT == MVT::i128) 1801235633Sdim LC = isSigned ? RTLIB::SDIV_I128 : RTLIB::UDIV_I128; 1802218893Sdim assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SDIV!"); 1803218893Sdim 1804218893Sdim return ARMEmitLibcall(I, LC); 1805218893Sdim} 1806218893Sdim 1807235633Sdimbool ARMFastISel::SelectRem(const Instruction *I, bool isSigned) { 1808218893Sdim MVT VT; 1809226890Sdim Type *Ty = I->getType(); 1810218893Sdim if (!isTypeLegal(Ty, VT)) 1811218893Sdim return false; 1812218893Sdim 1813218893Sdim RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 1814218893Sdim if (VT == MVT::i8) 1815235633Sdim LC = isSigned ? RTLIB::SREM_I8 : RTLIB::UREM_I8; 1816218893Sdim else if (VT == MVT::i16) 1817235633Sdim LC = isSigned ? RTLIB::SREM_I16 : RTLIB::UREM_I16; 1818218893Sdim else if (VT == MVT::i32) 1819235633Sdim LC = isSigned ? RTLIB::SREM_I32 : RTLIB::UREM_I32; 1820218893Sdim else if (VT == MVT::i64) 1821235633Sdim LC = isSigned ? RTLIB::SREM_I64 : RTLIB::UREM_I64; 1822218893Sdim else if (VT == MVT::i128) 1823235633Sdim LC = isSigned ? RTLIB::SREM_I128 : RTLIB::UREM_I128; 1824218893Sdim assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SREM!"); 1825218893Sdim 1826218893Sdim return ARMEmitLibcall(I, LC); 1827218893Sdim} 1828218893Sdim 1829235633Sdimbool ARMFastISel::SelectBinaryIntOp(const Instruction *I, unsigned ISDOpcode) { 1830235633Sdim EVT DestVT = TLI.getValueType(I->getType(), true); 1831235633Sdim 1832235633Sdim // We can get here in the case when we have a binary operation on a non-legal 1833235633Sdim // type and the target independent selector doesn't know how to handle it. 1834235633Sdim if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1) 1835235633Sdim return false; 1836245431Sdim 1837235633Sdim unsigned Opc; 1838235633Sdim switch (ISDOpcode) { 1839235633Sdim default: return false; 1840235633Sdim case ISD::ADD: 1841235633Sdim Opc = isThumb2 ? ARM::t2ADDrr : ARM::ADDrr; 1842235633Sdim break; 1843235633Sdim case ISD::OR: 1844235633Sdim Opc = isThumb2 ? ARM::t2ORRrr : ARM::ORRrr; 1845235633Sdim break; 1846235633Sdim case ISD::SUB: 1847235633Sdim Opc = isThumb2 ? ARM::t2SUBrr : ARM::SUBrr; 1848235633Sdim break; 1849235633Sdim } 1850235633Sdim 1851235633Sdim unsigned SrcReg1 = getRegForValue(I->getOperand(0)); 1852235633Sdim if (SrcReg1 == 0) return false; 1853235633Sdim 1854235633Sdim // TODO: Often the 2nd operand is an immediate, which can be encoded directly 1855235633Sdim // in the instruction, rather then materializing the value in a register. 1856235633Sdim unsigned SrcReg2 = getRegForValue(I->getOperand(1)); 1857235633Sdim if (SrcReg2 == 0) return false; 1858235633Sdim 1859263509Sdim unsigned ResultReg = createResultReg(&ARM::GPRnopcRegClass); 1860263509Sdim SrcReg1 = constrainOperandRegClass(TII.get(Opc), SrcReg1, 1); 1861263509Sdim SrcReg2 = constrainOperandRegClass(TII.get(Opc), SrcReg2, 2); 1862235633Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 1863235633Sdim TII.get(Opc), ResultReg) 1864235633Sdim .addReg(SrcReg1).addReg(SrcReg2)); 1865235633Sdim UpdateValueMap(I, ResultReg); 1866235633Sdim return true; 1867235633Sdim} 1868235633Sdim 1869235633Sdimbool ARMFastISel::SelectBinaryFPOp(const Instruction *I, unsigned ISDOpcode) { 1870252723Sdim EVT FPVT = TLI.getValueType(I->getType(), true); 1871252723Sdim if (!FPVT.isSimple()) return false; 1872252723Sdim MVT VT = FPVT.getSimpleVT(); 1873218893Sdim 1874218893Sdim // We can get here in the case when we want to use NEON for our fp 1875218893Sdim // operations, but can't figure out how to. Just use the vfp instructions 1876218893Sdim // if we have them. 1877218893Sdim // FIXME: It'd be nice to use NEON instructions. 1878226890Sdim Type *Ty = I->getType(); 1879218893Sdim bool isFloat = (Ty->isDoubleTy() || Ty->isFloatTy()); 1880218893Sdim if (isFloat && !Subtarget->hasVFP2()) 1881218893Sdim return false; 1882218893Sdim 1883218893Sdim unsigned Opc; 1884218893Sdim bool is64bit = VT == MVT::f64 || VT == MVT::i64; 1885218893Sdim switch (ISDOpcode) { 1886218893Sdim default: return false; 1887218893Sdim case ISD::FADD: 1888218893Sdim Opc = is64bit ? ARM::VADDD : ARM::VADDS; 1889218893Sdim break; 1890218893Sdim case ISD::FSUB: 1891218893Sdim Opc = is64bit ? ARM::VSUBD : ARM::VSUBS; 1892218893Sdim break; 1893218893Sdim case ISD::FMUL: 1894218893Sdim Opc = is64bit ? ARM::VMULD : ARM::VMULS; 1895218893Sdim break; 1896218893Sdim } 1897235633Sdim unsigned Op1 = getRegForValue(I->getOperand(0)); 1898235633Sdim if (Op1 == 0) return false; 1899235633Sdim 1900235633Sdim unsigned Op2 = getRegForValue(I->getOperand(1)); 1901235633Sdim if (Op2 == 0) return false; 1902235633Sdim 1903252723Sdim unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT.SimpleTy)); 1904218893Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 1905218893Sdim TII.get(Opc), ResultReg) 1906218893Sdim .addReg(Op1).addReg(Op2)); 1907218893Sdim UpdateValueMap(I, ResultReg); 1908218893Sdim return true; 1909218893Sdim} 1910218893Sdim 1911218893Sdim// Call Handling Code 1912218893Sdim 1913245431Sdim// This is largely taken directly from CCAssignFnForNode 1914218893Sdim// TODO: We may not support all of this. 1915245431SdimCCAssignFn *ARMFastISel::CCAssignFnForCall(CallingConv::ID CC, 1916245431Sdim bool Return, 1917245431Sdim bool isVarArg) { 1918218893Sdim switch (CC) { 1919218893Sdim default: 1920218893Sdim llvm_unreachable("Unsupported calling convention"); 1921218893Sdim case CallingConv::Fast: 1922245431Sdim if (Subtarget->hasVFP2() && !isVarArg) { 1923245431Sdim if (!Subtarget->isAAPCS_ABI()) 1924245431Sdim return (Return ? RetFastCC_ARM_APCS : FastCC_ARM_APCS); 1925245431Sdim // For AAPCS ABI targets, just use VFP variant of the calling convention. 1926245431Sdim return (Return ? RetCC_ARM_AAPCS_VFP : CC_ARM_AAPCS_VFP); 1927245431Sdim } 1928218893Sdim // Fallthrough 1929218893Sdim case CallingConv::C: 1930218893Sdim // Use target triple & subtarget features to do actual dispatch. 1931218893Sdim if (Subtarget->isAAPCS_ABI()) { 1932218893Sdim if (Subtarget->hasVFP2() && 1933245431Sdim TM.Options.FloatABIType == FloatABI::Hard && !isVarArg) 1934218893Sdim return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP); 1935218893Sdim else 1936218893Sdim return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS); 1937218893Sdim } else 1938218893Sdim return (Return ? RetCC_ARM_APCS: CC_ARM_APCS); 1939218893Sdim case CallingConv::ARM_AAPCS_VFP: 1940245431Sdim if (!isVarArg) 1941245431Sdim return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP); 1942245431Sdim // Fall through to soft float variant, variadic functions don't 1943245431Sdim // use hard floating point ABI. 1944218893Sdim case CallingConv::ARM_AAPCS: 1945218893Sdim return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS); 1946218893Sdim case CallingConv::ARM_APCS: 1947218893Sdim return (Return ? RetCC_ARM_APCS: CC_ARM_APCS); 1948245431Sdim case CallingConv::GHC: 1949245431Sdim if (Return) 1950245431Sdim llvm_unreachable("Can't return in GHC call convention"); 1951245431Sdim else 1952245431Sdim return CC_ARM_APCS_GHC; 1953218893Sdim } 1954218893Sdim} 1955218893Sdim 1956218893Sdimbool ARMFastISel::ProcessCallArgs(SmallVectorImpl<Value*> &Args, 1957218893Sdim SmallVectorImpl<unsigned> &ArgRegs, 1958218893Sdim SmallVectorImpl<MVT> &ArgVTs, 1959218893Sdim SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags, 1960218893Sdim SmallVectorImpl<unsigned> &RegArgs, 1961218893Sdim CallingConv::ID CC, 1962245431Sdim unsigned &NumBytes, 1963245431Sdim bool isVarArg) { 1964218893Sdim SmallVector<CCValAssign, 16> ArgLocs; 1965245431Sdim CCState CCInfo(CC, isVarArg, *FuncInfo.MF, TM, ArgLocs, *Context); 1966245431Sdim CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags, 1967245431Sdim CCAssignFnForCall(CC, false, isVarArg)); 1968218893Sdim 1969235633Sdim // Check that we can handle all of the arguments. If we can't, then bail out 1970235633Sdim // now before we add code to the MBB. 1971235633Sdim for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 1972235633Sdim CCValAssign &VA = ArgLocs[i]; 1973235633Sdim MVT ArgVT = ArgVTs[VA.getValNo()]; 1974235633Sdim 1975235633Sdim // We don't handle NEON/vector parameters yet. 1976235633Sdim if (ArgVT.isVector() || ArgVT.getSizeInBits() > 64) 1977235633Sdim return false; 1978235633Sdim 1979235633Sdim // Now copy/store arg to correct locations. 1980235633Sdim if (VA.isRegLoc() && !VA.needsCustom()) { 1981235633Sdim continue; 1982235633Sdim } else if (VA.needsCustom()) { 1983235633Sdim // TODO: We need custom lowering for vector (v2f64) args. 1984235633Sdim if (VA.getLocVT() != MVT::f64 || 1985235633Sdim // TODO: Only handle register args for now. 1986235633Sdim !VA.isRegLoc() || !ArgLocs[++i].isRegLoc()) 1987235633Sdim return false; 1988235633Sdim } else { 1989263509Sdim switch (ArgVT.SimpleTy) { 1990235633Sdim default: 1991235633Sdim return false; 1992235633Sdim case MVT::i1: 1993235633Sdim case MVT::i8: 1994235633Sdim case MVT::i16: 1995235633Sdim case MVT::i32: 1996235633Sdim break; 1997235633Sdim case MVT::f32: 1998235633Sdim if (!Subtarget->hasVFP2()) 1999235633Sdim return false; 2000235633Sdim break; 2001235633Sdim case MVT::f64: 2002235633Sdim if (!Subtarget->hasVFP2()) 2003235633Sdim return false; 2004235633Sdim break; 2005235633Sdim } 2006235633Sdim } 2007235633Sdim } 2008235633Sdim 2009235633Sdim // At the point, we are able to handle the call's arguments in fast isel. 2010235633Sdim 2011218893Sdim // Get a count of how many bytes are to be pushed on the stack. 2012218893Sdim NumBytes = CCInfo.getNextStackOffset(); 2013218893Sdim 2014218893Sdim // Issue CALLSEQ_START 2015224145Sdim unsigned AdjStackDown = TII.getCallFrameSetupOpcode(); 2016218893Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 2017218893Sdim TII.get(AdjStackDown)) 2018218893Sdim .addImm(NumBytes)); 2019218893Sdim 2020218893Sdim // Process the args. 2021218893Sdim for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 2022218893Sdim CCValAssign &VA = ArgLocs[i]; 2023218893Sdim unsigned Arg = ArgRegs[VA.getValNo()]; 2024218893Sdim MVT ArgVT = ArgVTs[VA.getValNo()]; 2025218893Sdim 2026235633Sdim assert((!ArgVT.isVector() && ArgVT.getSizeInBits() <= 64) && 2027235633Sdim "We don't handle NEON/vector parameters yet."); 2028218893Sdim 2029218893Sdim // Handle arg promotion, etc. 2030218893Sdim switch (VA.getLocInfo()) { 2031218893Sdim case CCValAssign::Full: break; 2032218893Sdim case CCValAssign::SExt: { 2033235633Sdim MVT DestVT = VA.getLocVT(); 2034235633Sdim Arg = ARMEmitIntExt(ArgVT, Arg, DestVT, /*isZExt*/false); 2035235633Sdim assert (Arg != 0 && "Failed to emit a sext"); 2036235633Sdim ArgVT = DestVT; 2037218893Sdim break; 2038218893Sdim } 2039235633Sdim case CCValAssign::AExt: 2040235633Sdim // Intentional fall-through. Handle AExt and ZExt. 2041218893Sdim case CCValAssign::ZExt: { 2042235633Sdim MVT DestVT = VA.getLocVT(); 2043235633Sdim Arg = ARMEmitIntExt(ArgVT, Arg, DestVT, /*isZExt*/true); 2044263509Sdim assert (Arg != 0 && "Failed to emit a zext"); 2045235633Sdim ArgVT = DestVT; 2046218893Sdim break; 2047218893Sdim } 2048218893Sdim case CCValAssign::BCvt: { 2049218893Sdim unsigned BC = FastEmit_r(ArgVT, VA.getLocVT(), ISD::BITCAST, Arg, 2050218893Sdim /*TODO: Kill=*/false); 2051218893Sdim assert(BC != 0 && "Failed to emit a bitcast!"); 2052218893Sdim Arg = BC; 2053218893Sdim ArgVT = VA.getLocVT(); 2054218893Sdim break; 2055218893Sdim } 2056218893Sdim default: llvm_unreachable("Unknown arg promotion!"); 2057218893Sdim } 2058218893Sdim 2059218893Sdim // Now copy/store arg to correct locations. 2060218893Sdim if (VA.isRegLoc() && !VA.needsCustom()) { 2061218893Sdim BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), 2062218893Sdim VA.getLocReg()) 2063235633Sdim .addReg(Arg); 2064218893Sdim RegArgs.push_back(VA.getLocReg()); 2065218893Sdim } else if (VA.needsCustom()) { 2066218893Sdim // TODO: We need custom lowering for vector (v2f64) args. 2067235633Sdim assert(VA.getLocVT() == MVT::f64 && 2068235633Sdim "Custom lowering for v2f64 args not available"); 2069218893Sdim 2070218893Sdim CCValAssign &NextVA = ArgLocs[++i]; 2071218893Sdim 2072235633Sdim assert(VA.isRegLoc() && NextVA.isRegLoc() && 2073235633Sdim "We only handle register args!"); 2074218893Sdim 2075218893Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 2076218893Sdim TII.get(ARM::VMOVRRD), VA.getLocReg()) 2077218893Sdim .addReg(NextVA.getLocReg(), RegState::Define) 2078218893Sdim .addReg(Arg)); 2079218893Sdim RegArgs.push_back(VA.getLocReg()); 2080218893Sdim RegArgs.push_back(NextVA.getLocReg()); 2081218893Sdim } else { 2082218893Sdim assert(VA.isMemLoc()); 2083218893Sdim // Need to store on the stack. 2084218893Sdim Address Addr; 2085218893Sdim Addr.BaseType = Address::RegBase; 2086218893Sdim Addr.Base.Reg = ARM::SP; 2087218893Sdim Addr.Offset = VA.getLocMemOffset(); 2088218893Sdim 2089235633Sdim bool EmitRet = ARMEmitStore(ArgVT, Arg, Addr); (void)EmitRet; 2090235633Sdim assert(EmitRet && "Could not emit a store for argument!"); 2091218893Sdim } 2092218893Sdim } 2093235633Sdim 2094218893Sdim return true; 2095218893Sdim} 2096218893Sdim 2097218893Sdimbool ARMFastISel::FinishCall(MVT RetVT, SmallVectorImpl<unsigned> &UsedRegs, 2098218893Sdim const Instruction *I, CallingConv::ID CC, 2099245431Sdim unsigned &NumBytes, bool isVarArg) { 2100218893Sdim // Issue CALLSEQ_END 2101224145Sdim unsigned AdjStackUp = TII.getCallFrameDestroyOpcode(); 2102218893Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 2103218893Sdim TII.get(AdjStackUp)) 2104218893Sdim .addImm(NumBytes).addImm(0)); 2105218893Sdim 2106218893Sdim // Now the return value. 2107218893Sdim if (RetVT != MVT::isVoid) { 2108218893Sdim SmallVector<CCValAssign, 16> RVLocs; 2109245431Sdim CCState CCInfo(CC, isVarArg, *FuncInfo.MF, TM, RVLocs, *Context); 2110245431Sdim CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true, isVarArg)); 2111218893Sdim 2112218893Sdim // Copy all of the result registers out of their specified physreg. 2113218893Sdim if (RVLocs.size() == 2 && RetVT == MVT::f64) { 2114218893Sdim // For this move we copy into two registers and then move into the 2115218893Sdim // double fp reg we want. 2116252723Sdim MVT DestVT = RVLocs[0].getValVT(); 2117235633Sdim const TargetRegisterClass* DstRC = TLI.getRegClassFor(DestVT); 2118218893Sdim unsigned ResultReg = createResultReg(DstRC); 2119218893Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 2120218893Sdim TII.get(ARM::VMOVDRR), ResultReg) 2121218893Sdim .addReg(RVLocs[0].getLocReg()) 2122218893Sdim .addReg(RVLocs[1].getLocReg())); 2123218893Sdim 2124218893Sdim UsedRegs.push_back(RVLocs[0].getLocReg()); 2125218893Sdim UsedRegs.push_back(RVLocs[1].getLocReg()); 2126218893Sdim 2127218893Sdim // Finally update the result. 2128218893Sdim UpdateValueMap(I, ResultReg); 2129218893Sdim } else { 2130218893Sdim assert(RVLocs.size() == 1 &&"Can't handle non-double multi-reg retvals!"); 2131252723Sdim MVT CopyVT = RVLocs[0].getValVT(); 2132218893Sdim 2133235633Sdim // Special handling for extended integers. 2134235633Sdim if (RetVT == MVT::i1 || RetVT == MVT::i8 || RetVT == MVT::i16) 2135235633Sdim CopyVT = MVT::i32; 2136235633Sdim 2137235633Sdim const TargetRegisterClass* DstRC = TLI.getRegClassFor(CopyVT); 2138235633Sdim 2139218893Sdim unsigned ResultReg = createResultReg(DstRC); 2140218893Sdim BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), 2141218893Sdim ResultReg).addReg(RVLocs[0].getLocReg()); 2142218893Sdim UsedRegs.push_back(RVLocs[0].getLocReg()); 2143218893Sdim 2144218893Sdim // Finally update the result. 2145218893Sdim UpdateValueMap(I, ResultReg); 2146218893Sdim } 2147218893Sdim } 2148218893Sdim 2149218893Sdim return true; 2150218893Sdim} 2151218893Sdim 2152218893Sdimbool ARMFastISel::SelectRet(const Instruction *I) { 2153218893Sdim const ReturnInst *Ret = cast<ReturnInst>(I); 2154218893Sdim const Function &F = *I->getParent()->getParent(); 2155218893Sdim 2156218893Sdim if (!FuncInfo.CanLowerReturn) 2157218893Sdim return false; 2158218893Sdim 2159252723Sdim // Build a list of return value registers. 2160252723Sdim SmallVector<unsigned, 4> RetRegs; 2161252723Sdim 2162218893Sdim CallingConv::ID CC = F.getCallingConv(); 2163218893Sdim if (Ret->getNumOperands() > 0) { 2164218893Sdim SmallVector<ISD::OutputArg, 4> Outs; 2165252723Sdim GetReturnInfo(F.getReturnType(), F.getAttributes(), Outs, TLI); 2166218893Sdim 2167218893Sdim // Analyze operands of the call, assigning locations to each operand. 2168218893Sdim SmallVector<CCValAssign, 16> ValLocs; 2169226890Sdim CCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, TM, ValLocs,I->getContext()); 2170245431Sdim CCInfo.AnalyzeReturn(Outs, CCAssignFnForCall(CC, true /* is Ret */, 2171245431Sdim F.isVarArg())); 2172218893Sdim 2173218893Sdim const Value *RV = Ret->getOperand(0); 2174218893Sdim unsigned Reg = getRegForValue(RV); 2175218893Sdim if (Reg == 0) 2176218893Sdim return false; 2177218893Sdim 2178218893Sdim // Only handle a single return value for now. 2179218893Sdim if (ValLocs.size() != 1) 2180218893Sdim return false; 2181218893Sdim 2182218893Sdim CCValAssign &VA = ValLocs[0]; 2183218893Sdim 2184218893Sdim // Don't bother handling odd stuff for now. 2185218893Sdim if (VA.getLocInfo() != CCValAssign::Full) 2186218893Sdim return false; 2187218893Sdim // Only handle register returns for now. 2188218893Sdim if (!VA.isRegLoc()) 2189218893Sdim return false; 2190218893Sdim 2191235633Sdim unsigned SrcReg = Reg + VA.getValNo(); 2192252723Sdim EVT RVEVT = TLI.getValueType(RV->getType()); 2193252723Sdim if (!RVEVT.isSimple()) return false; 2194252723Sdim MVT RVVT = RVEVT.getSimpleVT(); 2195252723Sdim MVT DestVT = VA.getValVT(); 2196235633Sdim // Special handling for extended integers. 2197235633Sdim if (RVVT != DestVT) { 2198235633Sdim if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16) 2199235633Sdim return false; 2200235633Sdim 2201235633Sdim assert(DestVT == MVT::i32 && "ARM should always ext to i32"); 2202235633Sdim 2203235633Sdim // Perform extension if flagged as either zext or sext. Otherwise, do 2204235633Sdim // nothing. 2205235633Sdim if (Outs[0].Flags.isZExt() || Outs[0].Flags.isSExt()) { 2206235633Sdim SrcReg = ARMEmitIntExt(RVVT, SrcReg, DestVT, Outs[0].Flags.isZExt()); 2207235633Sdim if (SrcReg == 0) return false; 2208235633Sdim } 2209235633Sdim } 2210235633Sdim 2211218893Sdim // Make the copy. 2212218893Sdim unsigned DstReg = VA.getLocReg(); 2213218893Sdim const TargetRegisterClass* SrcRC = MRI.getRegClass(SrcReg); 2214218893Sdim // Avoid a cross-class copy. This is very unlikely. 2215218893Sdim if (!SrcRC->contains(DstReg)) 2216218893Sdim return false; 2217218893Sdim BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), 2218218893Sdim DstReg).addReg(SrcReg); 2219218893Sdim 2220252723Sdim // Add register to return instruction. 2221252723Sdim RetRegs.push_back(VA.getLocReg()); 2222218893Sdim } 2223218893Sdim 2224235633Sdim unsigned RetOpc = isThumb2 ? ARM::tBX_RET : ARM::BX_RET; 2225252723Sdim MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 2226252723Sdim TII.get(RetOpc)); 2227252723Sdim AddOptionalDefs(MIB); 2228252723Sdim for (unsigned i = 0, e = RetRegs.size(); i != e; ++i) 2229252723Sdim MIB.addReg(RetRegs[i], RegState::Implicit); 2230218893Sdim return true; 2231218893Sdim} 2232218893Sdim 2233245431Sdimunsigned ARMFastISel::ARMSelectCallOp(bool UseReg) { 2234245431Sdim if (UseReg) 2235245431Sdim return isThumb2 ? ARM::tBLXr : ARM::BLX; 2236245431Sdim else 2237245431Sdim return isThumb2 ? ARM::tBL : ARM::BL; 2238219077Sdim} 2239219077Sdim 2240245431Sdimunsigned ARMFastISel::getLibcallReg(const Twine &Name) { 2241263509Sdim // Manually compute the global's type to avoid building it when unnecessary. 2242263509Sdim Type *GVTy = Type::getInt32PtrTy(*Context, /*AS=*/0); 2243263509Sdim EVT LCREVT = TLI.getValueType(GVTy); 2244263509Sdim if (!LCREVT.isSimple()) return 0; 2245263509Sdim 2246245431Sdim GlobalValue *GV = new GlobalVariable(Type::getInt32Ty(*Context), false, 2247245431Sdim GlobalValue::ExternalLinkage, 0, Name); 2248263509Sdim assert(GV->getType() == GVTy && "We miscomputed the type for the global!"); 2249252723Sdim return ARMMaterializeGV(GV, LCREVT.getSimpleVT()); 2250245431Sdim} 2251245431Sdim 2252218893Sdim// A quick function that will emit a call for a named libcall in F with the 2253218893Sdim// vector of passed arguments for the Instruction in I. We can assume that we 2254218893Sdim// can emit a call for any libcall we can produce. This is an abridged version 2255218893Sdim// of the full call infrastructure since we won't need to worry about things 2256218893Sdim// like computed function pointers or strange arguments at call sites. 2257218893Sdim// TODO: Try to unify this and the normal call bits for ARM, then try to unify 2258218893Sdim// with X86. 2259218893Sdimbool ARMFastISel::ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call) { 2260218893Sdim CallingConv::ID CC = TLI.getLibcallCallingConv(Call); 2261218893Sdim 2262218893Sdim // Handle *simple* calls for now. 2263226890Sdim Type *RetTy = I->getType(); 2264218893Sdim MVT RetVT; 2265218893Sdim if (RetTy->isVoidTy()) 2266218893Sdim RetVT = MVT::isVoid; 2267218893Sdim else if (!isTypeLegal(RetTy, RetVT)) 2268218893Sdim return false; 2269218893Sdim 2270245431Sdim // Can't handle non-double multi-reg retvals. 2271245431Sdim if (RetVT != MVT::isVoid && RetVT != MVT::i32) { 2272245431Sdim SmallVector<CCValAssign, 16> RVLocs; 2273245431Sdim CCState CCInfo(CC, false, *FuncInfo.MF, TM, RVLocs, *Context); 2274245431Sdim CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true, false)); 2275245431Sdim if (RVLocs.size() >= 2 && RetVT != MVT::f64) 2276245431Sdim return false; 2277245431Sdim } 2278218893Sdim 2279218893Sdim // Set up the argument vectors. 2280218893Sdim SmallVector<Value*, 8> Args; 2281218893Sdim SmallVector<unsigned, 8> ArgRegs; 2282218893Sdim SmallVector<MVT, 8> ArgVTs; 2283218893Sdim SmallVector<ISD::ArgFlagsTy, 8> ArgFlags; 2284218893Sdim Args.reserve(I->getNumOperands()); 2285218893Sdim ArgRegs.reserve(I->getNumOperands()); 2286218893Sdim ArgVTs.reserve(I->getNumOperands()); 2287218893Sdim ArgFlags.reserve(I->getNumOperands()); 2288218893Sdim for (unsigned i = 0; i < I->getNumOperands(); ++i) { 2289218893Sdim Value *Op = I->getOperand(i); 2290218893Sdim unsigned Arg = getRegForValue(Op); 2291218893Sdim if (Arg == 0) return false; 2292218893Sdim 2293226890Sdim Type *ArgTy = Op->getType(); 2294218893Sdim MVT ArgVT; 2295218893Sdim if (!isTypeLegal(ArgTy, ArgVT)) return false; 2296218893Sdim 2297218893Sdim ISD::ArgFlagsTy Flags; 2298218893Sdim unsigned OriginalAlignment = TD.getABITypeAlignment(ArgTy); 2299218893Sdim Flags.setOrigAlign(OriginalAlignment); 2300218893Sdim 2301218893Sdim Args.push_back(Op); 2302218893Sdim ArgRegs.push_back(Arg); 2303218893Sdim ArgVTs.push_back(ArgVT); 2304218893Sdim ArgFlags.push_back(Flags); 2305218893Sdim } 2306218893Sdim 2307218893Sdim // Handle the arguments now that we've gotten them. 2308218893Sdim SmallVector<unsigned, 4> RegArgs; 2309218893Sdim unsigned NumBytes; 2310245431Sdim if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags, 2311245431Sdim RegArgs, CC, NumBytes, false)) 2312218893Sdim return false; 2313218893Sdim 2314245431Sdim unsigned CalleeReg = 0; 2315245431Sdim if (EnableARMLongCalls) { 2316245431Sdim CalleeReg = getLibcallReg(TLI.getLibcallName(Call)); 2317245431Sdim if (CalleeReg == 0) return false; 2318245431Sdim } 2319245431Sdim 2320235633Sdim // Issue the call. 2321245431Sdim unsigned CallOpc = ARMSelectCallOp(EnableARMLongCalls); 2322245431Sdim MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, 2323245431Sdim DL, TII.get(CallOpc)); 2324245431Sdim // BL / BLX don't take a predicate, but tBL / tBLX do. 2325235633Sdim if (isThumb2) 2326245431Sdim AddDefaultPred(MIB); 2327245431Sdim if (EnableARMLongCalls) 2328245431Sdim MIB.addReg(CalleeReg); 2329219077Sdim else 2330245431Sdim MIB.addExternalSymbol(TLI.getLibcallName(Call)); 2331218893Sdim 2332218893Sdim // Add implicit physical register uses to the call. 2333218893Sdim for (unsigned i = 0, e = RegArgs.size(); i != e; ++i) 2334245431Sdim MIB.addReg(RegArgs[i], RegState::Implicit); 2335218893Sdim 2336235633Sdim // Add a register mask with the call-preserved registers. 2337235633Sdim // Proper defs for return values will be added by setPhysRegsDeadExcept(). 2338235633Sdim MIB.addRegMask(TRI.getCallPreservedMask(CC)); 2339235633Sdim 2340218893Sdim // Finish off the call including any return values. 2341218893Sdim SmallVector<unsigned, 4> UsedRegs; 2342245431Sdim if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes, false)) return false; 2343218893Sdim 2344218893Sdim // Set all unused physreg defs as dead. 2345218893Sdim static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI); 2346218893Sdim 2347218893Sdim return true; 2348218893Sdim} 2349218893Sdim 2350235633Sdimbool ARMFastISel::SelectCall(const Instruction *I, 2351235633Sdim const char *IntrMemName = 0) { 2352218893Sdim const CallInst *CI = cast<CallInst>(I); 2353218893Sdim const Value *Callee = CI->getCalledValue(); 2354218893Sdim 2355235633Sdim // Can't handle inline asm. 2356235633Sdim if (isa<InlineAsm>(Callee)) return false; 2357218893Sdim 2358252723Sdim // Allow SelectionDAG isel to handle tail calls. 2359252723Sdim if (CI->isTailCall()) return false; 2360252723Sdim 2361218893Sdim // Check the calling convention. 2362218893Sdim ImmutableCallSite CS(CI); 2363218893Sdim CallingConv::ID CC = CS.getCallingConv(); 2364218893Sdim 2365218893Sdim // TODO: Avoid some calling conventions? 2366218893Sdim 2367226890Sdim PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType()); 2368226890Sdim FunctionType *FTy = cast<FunctionType>(PT->getElementType()); 2369245431Sdim bool isVarArg = FTy->isVarArg(); 2370218893Sdim 2371218893Sdim // Handle *simple* calls for now. 2372226890Sdim Type *RetTy = I->getType(); 2373218893Sdim MVT RetVT; 2374218893Sdim if (RetTy->isVoidTy()) 2375218893Sdim RetVT = MVT::isVoid; 2376235633Sdim else if (!isTypeLegal(RetTy, RetVT) && RetVT != MVT::i16 && 2377235633Sdim RetVT != MVT::i8 && RetVT != MVT::i1) 2378218893Sdim return false; 2379218893Sdim 2380245431Sdim // Can't handle non-double multi-reg retvals. 2381245431Sdim if (RetVT != MVT::isVoid && RetVT != MVT::i1 && RetVT != MVT::i8 && 2382245431Sdim RetVT != MVT::i16 && RetVT != MVT::i32) { 2383245431Sdim SmallVector<CCValAssign, 16> RVLocs; 2384245431Sdim CCState CCInfo(CC, isVarArg, *FuncInfo.MF, TM, RVLocs, *Context); 2385245431Sdim CCInfo.AnalyzeCallResult(RetVT, CCAssignFnForCall(CC, true, isVarArg)); 2386245431Sdim if (RVLocs.size() >= 2 && RetVT != MVT::f64) 2387245431Sdim return false; 2388245431Sdim } 2389221345Sdim 2390218893Sdim // Set up the argument vectors. 2391218893Sdim SmallVector<Value*, 8> Args; 2392218893Sdim SmallVector<unsigned, 8> ArgRegs; 2393218893Sdim SmallVector<MVT, 8> ArgVTs; 2394218893Sdim SmallVector<ISD::ArgFlagsTy, 8> ArgFlags; 2395235633Sdim unsigned arg_size = CS.arg_size(); 2396235633Sdim Args.reserve(arg_size); 2397235633Sdim ArgRegs.reserve(arg_size); 2398235633Sdim ArgVTs.reserve(arg_size); 2399235633Sdim ArgFlags.reserve(arg_size); 2400218893Sdim for (ImmutableCallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end(); 2401218893Sdim i != e; ++i) { 2402235633Sdim // If we're lowering a memory intrinsic instead of a regular call, skip the 2403235633Sdim // last two arguments, which shouldn't be passed to the underlying function. 2404235633Sdim if (IntrMemName && e-i <= 2) 2405235633Sdim break; 2406218893Sdim 2407218893Sdim ISD::ArgFlagsTy Flags; 2408218893Sdim unsigned AttrInd = i - CS.arg_begin() + 1; 2409252723Sdim if (CS.paramHasAttr(AttrInd, Attribute::SExt)) 2410218893Sdim Flags.setSExt(); 2411252723Sdim if (CS.paramHasAttr(AttrInd, Attribute::ZExt)) 2412218893Sdim Flags.setZExt(); 2413218893Sdim 2414235633Sdim // FIXME: Only handle *easy* calls for now. 2415252723Sdim if (CS.paramHasAttr(AttrInd, Attribute::InReg) || 2416252723Sdim CS.paramHasAttr(AttrInd, Attribute::StructRet) || 2417252723Sdim CS.paramHasAttr(AttrInd, Attribute::Nest) || 2418252723Sdim CS.paramHasAttr(AttrInd, Attribute::ByVal)) 2419218893Sdim return false; 2420218893Sdim 2421226890Sdim Type *ArgTy = (*i)->getType(); 2422218893Sdim MVT ArgVT; 2423235633Sdim if (!isTypeLegal(ArgTy, ArgVT) && ArgVT != MVT::i16 && ArgVT != MVT::i8 && 2424235633Sdim ArgVT != MVT::i1) 2425218893Sdim return false; 2426235633Sdim 2427235633Sdim unsigned Arg = getRegForValue(*i); 2428235633Sdim if (Arg == 0) 2429235633Sdim return false; 2430235633Sdim 2431218893Sdim unsigned OriginalAlignment = TD.getABITypeAlignment(ArgTy); 2432218893Sdim Flags.setOrigAlign(OriginalAlignment); 2433218893Sdim 2434218893Sdim Args.push_back(*i); 2435218893Sdim ArgRegs.push_back(Arg); 2436218893Sdim ArgVTs.push_back(ArgVT); 2437218893Sdim ArgFlags.push_back(Flags); 2438218893Sdim } 2439218893Sdim 2440218893Sdim // Handle the arguments now that we've gotten them. 2441218893Sdim SmallVector<unsigned, 4> RegArgs; 2442218893Sdim unsigned NumBytes; 2443245431Sdim if (!ProcessCallArgs(Args, ArgRegs, ArgVTs, ArgFlags, 2444245431Sdim RegArgs, CC, NumBytes, isVarArg)) 2445218893Sdim return false; 2446218893Sdim 2447245431Sdim bool UseReg = false; 2448245431Sdim const GlobalValue *GV = dyn_cast<GlobalValue>(Callee); 2449245431Sdim if (!GV || EnableARMLongCalls) UseReg = true; 2450245431Sdim 2451245431Sdim unsigned CalleeReg = 0; 2452245431Sdim if (UseReg) { 2453245431Sdim if (IntrMemName) 2454245431Sdim CalleeReg = getLibcallReg(IntrMemName); 2455235633Sdim else 2456245431Sdim CalleeReg = getRegForValue(Callee); 2457245431Sdim 2458245431Sdim if (CalleeReg == 0) return false; 2459235633Sdim } 2460245431Sdim 2461245431Sdim // Issue the call. 2462245431Sdim unsigned CallOpc = ARMSelectCallOp(UseReg); 2463245431Sdim MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, 2464245431Sdim DL, TII.get(CallOpc)); 2465245431Sdim 2466263509Sdim unsigned char OpFlags = 0; 2467263509Sdim 2468263509Sdim // Add MO_PLT for global address or external symbol in the PIC relocation 2469263509Sdim // model. 2470263509Sdim if (Subtarget->isTargetELF() && TM.getRelocationModel() == Reloc::PIC_) 2471263509Sdim OpFlags = ARMII::MO_PLT; 2472263509Sdim 2473245431Sdim // ARM calls don't take a predicate, but tBL / tBLX do. 2474245431Sdim if(isThumb2) 2475245431Sdim AddDefaultPred(MIB); 2476245431Sdim if (UseReg) 2477245431Sdim MIB.addReg(CalleeReg); 2478245431Sdim else if (!IntrMemName) 2479263509Sdim MIB.addGlobalAddress(GV, 0, OpFlags); 2480245431Sdim else 2481263509Sdim MIB.addExternalSymbol(IntrMemName, OpFlags); 2482245431Sdim 2483218893Sdim // Add implicit physical register uses to the call. 2484218893Sdim for (unsigned i = 0, e = RegArgs.size(); i != e; ++i) 2485245431Sdim MIB.addReg(RegArgs[i], RegState::Implicit); 2486218893Sdim 2487235633Sdim // Add a register mask with the call-preserved registers. 2488235633Sdim // Proper defs for return values will be added by setPhysRegsDeadExcept(). 2489235633Sdim MIB.addRegMask(TRI.getCallPreservedMask(CC)); 2490235633Sdim 2491218893Sdim // Finish off the call including any return values. 2492218893Sdim SmallVector<unsigned, 4> UsedRegs; 2493245431Sdim if (!FinishCall(RetVT, UsedRegs, I, CC, NumBytes, isVarArg)) 2494245431Sdim return false; 2495218893Sdim 2496218893Sdim // Set all unused physreg defs as dead. 2497218893Sdim static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI); 2498218893Sdim 2499218893Sdim return true; 2500235633Sdim} 2501218893Sdim 2502235633Sdimbool ARMFastISel::ARMIsMemCpySmall(uint64_t Len) { 2503235633Sdim return Len <= 16; 2504218893Sdim} 2505218893Sdim 2506235633Sdimbool ARMFastISel::ARMTryEmitSmallMemCpy(Address Dest, Address Src, 2507252723Sdim uint64_t Len, unsigned Alignment) { 2508235633Sdim // Make sure we don't bloat code by inlining very large memcpy's. 2509235633Sdim if (!ARMIsMemCpySmall(Len)) 2510235633Sdim return false; 2511223017Sdim 2512235633Sdim while (Len) { 2513235633Sdim MVT VT; 2514252723Sdim if (!Alignment || Alignment >= 4) { 2515252723Sdim if (Len >= 4) 2516252723Sdim VT = MVT::i32; 2517252723Sdim else if (Len >= 2) 2518252723Sdim VT = MVT::i16; 2519252723Sdim else { 2520252723Sdim assert (Len == 1 && "Expected a length of 1!"); 2521252723Sdim VT = MVT::i8; 2522252723Sdim } 2523252723Sdim } else { 2524252723Sdim // Bound based on alignment. 2525252723Sdim if (Len >= 2 && Alignment == 2) 2526252723Sdim VT = MVT::i16; 2527252723Sdim else { 2528252723Sdim VT = MVT::i8; 2529252723Sdim } 2530235633Sdim } 2531223017Sdim 2532235633Sdim bool RV; 2533235633Sdim unsigned ResultReg; 2534235633Sdim RV = ARMEmitLoad(VT, ResultReg, Src); 2535235633Sdim assert (RV == true && "Should be able to handle this load."); 2536235633Sdim RV = ARMEmitStore(VT, ResultReg, Dest); 2537235633Sdim assert (RV == true && "Should be able to handle this store."); 2538235633Sdim (void)RV; 2539235633Sdim 2540235633Sdim unsigned Size = VT.getSizeInBits()/8; 2541235633Sdim Len -= Size; 2542235633Sdim Dest.Offset += Size; 2543235633Sdim Src.Offset += Size; 2544235633Sdim } 2545235633Sdim 2546235633Sdim return true; 2547235633Sdim} 2548235633Sdim 2549235633Sdimbool ARMFastISel::SelectIntrinsicCall(const IntrinsicInst &I) { 2550235633Sdim // FIXME: Handle more intrinsics. 2551235633Sdim switch (I.getIntrinsicID()) { 2552235633Sdim default: return false; 2553245431Sdim case Intrinsic::frameaddress: { 2554245431Sdim MachineFrameInfo *MFI = FuncInfo.MF->getFrameInfo(); 2555245431Sdim MFI->setFrameAddressIsTaken(true); 2556245431Sdim 2557245431Sdim unsigned LdrOpc; 2558245431Sdim const TargetRegisterClass *RC; 2559245431Sdim if (isThumb2) { 2560245431Sdim LdrOpc = ARM::t2LDRi12; 2561245431Sdim RC = (const TargetRegisterClass*)&ARM::tGPRRegClass; 2562245431Sdim } else { 2563245431Sdim LdrOpc = ARM::LDRi12; 2564245431Sdim RC = (const TargetRegisterClass*)&ARM::GPRRegClass; 2565245431Sdim } 2566245431Sdim 2567245431Sdim const ARMBaseRegisterInfo *RegInfo = 2568245431Sdim static_cast<const ARMBaseRegisterInfo*>(TM.getRegisterInfo()); 2569245431Sdim unsigned FramePtr = RegInfo->getFrameRegister(*(FuncInfo.MF)); 2570245431Sdim unsigned SrcReg = FramePtr; 2571245431Sdim 2572245431Sdim // Recursively load frame address 2573245431Sdim // ldr r0 [fp] 2574245431Sdim // ldr r0 [r0] 2575245431Sdim // ldr r0 [r0] 2576245431Sdim // ... 2577245431Sdim unsigned DestReg; 2578245431Sdim unsigned Depth = cast<ConstantInt>(I.getOperand(0))->getZExtValue(); 2579245431Sdim while (Depth--) { 2580245431Sdim DestReg = createResultReg(RC); 2581245431Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 2582245431Sdim TII.get(LdrOpc), DestReg) 2583245431Sdim .addReg(SrcReg).addImm(0)); 2584245431Sdim SrcReg = DestReg; 2585245431Sdim } 2586245431Sdim UpdateValueMap(&I, SrcReg); 2587245431Sdim return true; 2588245431Sdim } 2589235633Sdim case Intrinsic::memcpy: 2590235633Sdim case Intrinsic::memmove: { 2591235633Sdim const MemTransferInst &MTI = cast<MemTransferInst>(I); 2592235633Sdim // Don't handle volatile. 2593235633Sdim if (MTI.isVolatile()) 2594223017Sdim return false; 2595235633Sdim 2596235633Sdim // Disable inlining for memmove before calls to ComputeAddress. Otherwise, 2597235633Sdim // we would emit dead code because we don't currently handle memmoves. 2598235633Sdim bool isMemCpy = (I.getIntrinsicID() == Intrinsic::memcpy); 2599235633Sdim if (isa<ConstantInt>(MTI.getLength()) && isMemCpy) { 2600235633Sdim // Small memcpy's are common enough that we want to do them without a call 2601235633Sdim // if possible. 2602235633Sdim uint64_t Len = cast<ConstantInt>(MTI.getLength())->getZExtValue(); 2603235633Sdim if (ARMIsMemCpySmall(Len)) { 2604235633Sdim Address Dest, Src; 2605235633Sdim if (!ARMComputeAddress(MTI.getRawDest(), Dest) || 2606235633Sdim !ARMComputeAddress(MTI.getRawSource(), Src)) 2607235633Sdim return false; 2608252723Sdim unsigned Alignment = MTI.getAlignment(); 2609252723Sdim if (ARMTryEmitSmallMemCpy(Dest, Src, Len, Alignment)) 2610235633Sdim return true; 2611235633Sdim } 2612235633Sdim } 2613245431Sdim 2614235633Sdim if (!MTI.getLength()->getType()->isIntegerTy(32)) 2615223017Sdim return false; 2616245431Sdim 2617235633Sdim if (MTI.getSourceAddressSpace() > 255 || MTI.getDestAddressSpace() > 255) 2618235633Sdim return false; 2619223017Sdim 2620235633Sdim const char *IntrMemName = isa<MemCpyInst>(I) ? "memcpy" : "memmove"; 2621235633Sdim return SelectCall(&I, IntrMemName); 2622235633Sdim } 2623235633Sdim case Intrinsic::memset: { 2624235633Sdim const MemSetInst &MSI = cast<MemSetInst>(I); 2625235633Sdim // Don't handle volatile. 2626235633Sdim if (MSI.isVolatile()) 2627235633Sdim return false; 2628245431Sdim 2629235633Sdim if (!MSI.getLength()->getType()->isIntegerTy(32)) 2630235633Sdim return false; 2631245431Sdim 2632235633Sdim if (MSI.getDestAddressSpace() > 255) 2633235633Sdim return false; 2634245431Sdim 2635235633Sdim return SelectCall(&I, "memset"); 2636235633Sdim } 2637245431Sdim case Intrinsic::trap: { 2638252723Sdim BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get( 2639252723Sdim Subtarget->useNaClTrap() ? ARM::TRAPNaCl : ARM::TRAP)); 2640245431Sdim return true; 2641235633Sdim } 2642245431Sdim } 2643235633Sdim} 2644223017Sdim 2645235633Sdimbool ARMFastISel::SelectTrunc(const Instruction *I) { 2646245431Sdim // The high bits for a type smaller than the register size are assumed to be 2647235633Sdim // undefined. 2648235633Sdim Value *Op = I->getOperand(0); 2649235633Sdim 2650235633Sdim EVT SrcVT, DestVT; 2651235633Sdim SrcVT = TLI.getValueType(Op->getType(), true); 2652235633Sdim DestVT = TLI.getValueType(I->getType(), true); 2653235633Sdim 2654235633Sdim if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8) 2655223017Sdim return false; 2656235633Sdim if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1) 2657235633Sdim return false; 2658223017Sdim 2659235633Sdim unsigned SrcReg = getRegForValue(Op); 2660235633Sdim if (!SrcReg) return false; 2661235633Sdim 2662235633Sdim // Because the high bits are undefined, a truncate doesn't generate 2663235633Sdim // any code. 2664235633Sdim UpdateValueMap(I, SrcReg); 2665235633Sdim return true; 2666235633Sdim} 2667235633Sdim 2668252723Sdimunsigned ARMFastISel::ARMEmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, 2669235633Sdim bool isZExt) { 2670235633Sdim if (DestVT != MVT::i32 && DestVT != MVT::i16 && DestVT != MVT::i8) 2671235633Sdim return 0; 2672263509Sdim if (SrcVT != MVT::i16 && SrcVT != MVT::i8 && SrcVT != MVT::i1) 2673263509Sdim return 0; 2674235633Sdim 2675263509Sdim // Table of which combinations can be emitted as a single instruction, 2676263509Sdim // and which will require two. 2677263509Sdim static const uint8_t isSingleInstrTbl[3][2][2][2] = { 2678263509Sdim // ARM Thumb 2679263509Sdim // !hasV6Ops hasV6Ops !hasV6Ops hasV6Ops 2680263509Sdim // ext: s z s z s z s z 2681263509Sdim /* 1 */ { { { 0, 1 }, { 0, 1 } }, { { 0, 0 }, { 0, 1 } } }, 2682263509Sdim /* 8 */ { { { 0, 1 }, { 1, 1 } }, { { 0, 0 }, { 1, 1 } } }, 2683263509Sdim /* 16 */ { { { 0, 0 }, { 1, 1 } }, { { 0, 0 }, { 1, 1 } } } 2684263509Sdim }; 2685263509Sdim 2686263509Sdim // Target registers for: 2687263509Sdim // - For ARM can never be PC. 2688263509Sdim // - For 16-bit Thumb are restricted to lower 8 registers. 2689263509Sdim // - For 32-bit Thumb are restricted to non-SP and non-PC. 2690263509Sdim static const TargetRegisterClass *RCTbl[2][2] = { 2691263509Sdim // Instructions: Two Single 2692263509Sdim /* ARM */ { &ARM::GPRnopcRegClass, &ARM::GPRnopcRegClass }, 2693263509Sdim /* Thumb */ { &ARM::tGPRRegClass, &ARM::rGPRRegClass } 2694263509Sdim }; 2695263509Sdim 2696263509Sdim // Table governing the instruction(s) to be emitted. 2697263509Sdim static const struct InstructionTable { 2698263509Sdim uint32_t Opc : 16; 2699263509Sdim uint32_t hasS : 1; // Some instructions have an S bit, always set it to 0. 2700263509Sdim uint32_t Shift : 7; // For shift operand addressing mode, used by MOVsi. 2701263509Sdim uint32_t Imm : 8; // All instructions have either a shift or a mask. 2702263509Sdim } IT[2][2][3][2] = { 2703263509Sdim { // Two instructions (first is left shift, second is in this table). 2704263509Sdim { // ARM Opc S Shift Imm 2705263509Sdim /* 1 bit sext */ { { ARM::MOVsi , 1, ARM_AM::asr , 31 }, 2706263509Sdim /* 1 bit zext */ { ARM::MOVsi , 1, ARM_AM::lsr , 31 } }, 2707263509Sdim /* 8 bit sext */ { { ARM::MOVsi , 1, ARM_AM::asr , 24 }, 2708263509Sdim /* 8 bit zext */ { ARM::MOVsi , 1, ARM_AM::lsr , 24 } }, 2709263509Sdim /* 16 bit sext */ { { ARM::MOVsi , 1, ARM_AM::asr , 16 }, 2710263509Sdim /* 16 bit zext */ { ARM::MOVsi , 1, ARM_AM::lsr , 16 } } 2711263509Sdim }, 2712263509Sdim { // Thumb Opc S Shift Imm 2713263509Sdim /* 1 bit sext */ { { ARM::tASRri , 0, ARM_AM::no_shift, 31 }, 2714263509Sdim /* 1 bit zext */ { ARM::tLSRri , 0, ARM_AM::no_shift, 31 } }, 2715263509Sdim /* 8 bit sext */ { { ARM::tASRri , 0, ARM_AM::no_shift, 24 }, 2716263509Sdim /* 8 bit zext */ { ARM::tLSRri , 0, ARM_AM::no_shift, 24 } }, 2717263509Sdim /* 16 bit sext */ { { ARM::tASRri , 0, ARM_AM::no_shift, 16 }, 2718263509Sdim /* 16 bit zext */ { ARM::tLSRri , 0, ARM_AM::no_shift, 16 } } 2719263509Sdim } 2720263509Sdim }, 2721263509Sdim { // Single instruction. 2722263509Sdim { // ARM Opc S Shift Imm 2723263509Sdim /* 1 bit sext */ { { ARM::KILL , 0, ARM_AM::no_shift, 0 }, 2724263509Sdim /* 1 bit zext */ { ARM::ANDri , 1, ARM_AM::no_shift, 1 } }, 2725263509Sdim /* 8 bit sext */ { { ARM::SXTB , 0, ARM_AM::no_shift, 0 }, 2726263509Sdim /* 8 bit zext */ { ARM::ANDri , 1, ARM_AM::no_shift, 255 } }, 2727263509Sdim /* 16 bit sext */ { { ARM::SXTH , 0, ARM_AM::no_shift, 0 }, 2728263509Sdim /* 16 bit zext */ { ARM::UXTH , 0, ARM_AM::no_shift, 0 } } 2729263509Sdim }, 2730263509Sdim { // Thumb Opc S Shift Imm 2731263509Sdim /* 1 bit sext */ { { ARM::KILL , 0, ARM_AM::no_shift, 0 }, 2732263509Sdim /* 1 bit zext */ { ARM::t2ANDri, 1, ARM_AM::no_shift, 1 } }, 2733263509Sdim /* 8 bit sext */ { { ARM::t2SXTB , 0, ARM_AM::no_shift, 0 }, 2734263509Sdim /* 8 bit zext */ { ARM::t2ANDri, 1, ARM_AM::no_shift, 255 } }, 2735263509Sdim /* 16 bit sext */ { { ARM::t2SXTH , 0, ARM_AM::no_shift, 0 }, 2736263509Sdim /* 16 bit zext */ { ARM::t2UXTH , 0, ARM_AM::no_shift, 0 } } 2737263509Sdim } 2738223017Sdim } 2739263509Sdim }; 2740263509Sdim 2741263509Sdim unsigned SrcBits = SrcVT.getSizeInBits(); 2742263509Sdim unsigned DestBits = DestVT.getSizeInBits(); 2743263509Sdim (void) DestBits; 2744263509Sdim assert((SrcBits < DestBits) && "can only extend to larger types"); 2745263509Sdim assert((DestBits == 32 || DestBits == 16 || DestBits == 8) && 2746263509Sdim "other sizes unimplemented"); 2747263509Sdim assert((SrcBits == 16 || SrcBits == 8 || SrcBits == 1) && 2748263509Sdim "other sizes unimplemented"); 2749263509Sdim 2750263509Sdim bool hasV6Ops = Subtarget->hasV6Ops(); 2751263509Sdim unsigned Bitness = SrcBits / 8; // {1,8,16}=>{0,1,2} 2752263509Sdim assert((Bitness < 3) && "sanity-check table bounds"); 2753263509Sdim 2754263509Sdim bool isSingleInstr = isSingleInstrTbl[Bitness][isThumb2][hasV6Ops][isZExt]; 2755263509Sdim const TargetRegisterClass *RC = RCTbl[isThumb2][isSingleInstr]; 2756263509Sdim const InstructionTable *ITP = &IT[isSingleInstr][isThumb2][Bitness][isZExt]; 2757263509Sdim unsigned Opc = ITP->Opc; 2758263509Sdim assert(ARM::KILL != Opc && "Invalid table entry"); 2759263509Sdim unsigned hasS = ITP->hasS; 2760263509Sdim ARM_AM::ShiftOpc Shift = (ARM_AM::ShiftOpc) ITP->Shift; 2761263509Sdim assert(((Shift == ARM_AM::no_shift) == (Opc != ARM::MOVsi)) && 2762263509Sdim "only MOVsi has shift operand addressing mode"); 2763263509Sdim unsigned Imm = ITP->Imm; 2764263509Sdim 2765263509Sdim // 16-bit Thumb instructions always set CPSR (unless they're in an IT block). 2766263509Sdim bool setsCPSR = &ARM::tGPRRegClass == RC; 2767263509Sdim unsigned LSLOpc = isThumb2 ? ARM::tLSLri : ARM::MOVsi; 2768263509Sdim unsigned ResultReg; 2769263509Sdim // MOVsi encodes shift and immediate in shift operand addressing mode. 2770263509Sdim // The following condition has the same value when emitting two 2771263509Sdim // instruction sequences: both are shifts. 2772263509Sdim bool ImmIsSO = (Shift != ARM_AM::no_shift); 2773263509Sdim 2774263509Sdim // Either one or two instructions are emitted. 2775263509Sdim // They're always of the form: 2776263509Sdim // dst = in OP imm 2777263509Sdim // CPSR is set only by 16-bit Thumb instructions. 2778263509Sdim // Predicate, if any, is AL. 2779263509Sdim // S bit, if available, is always 0. 2780263509Sdim // When two are emitted the first's result will feed as the second's input, 2781263509Sdim // that value is then dead. 2782263509Sdim unsigned NumInstrsEmitted = isSingleInstr ? 1 : 2; 2783263509Sdim for (unsigned Instr = 0; Instr != NumInstrsEmitted; ++Instr) { 2784263509Sdim ResultReg = createResultReg(RC); 2785263509Sdim bool isLsl = (0 == Instr) && !isSingleInstr; 2786263509Sdim unsigned Opcode = isLsl ? LSLOpc : Opc; 2787263509Sdim ARM_AM::ShiftOpc ShiftAM = isLsl ? ARM_AM::lsl : Shift; 2788263509Sdim unsigned ImmEnc = ImmIsSO ? ARM_AM::getSORegOpc(ShiftAM, Imm) : Imm; 2789263509Sdim bool isKill = 1 == Instr; 2790263509Sdim MachineInstrBuilder MIB = BuildMI( 2791263509Sdim *FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opcode), ResultReg); 2792263509Sdim if (setsCPSR) 2793263509Sdim MIB.addReg(ARM::CPSR, RegState::Define); 2794263509Sdim SrcReg = constrainOperandRegClass(TII.get(Opcode), SrcReg, 1 + setsCPSR); 2795263509Sdim AddDefaultPred(MIB.addReg(SrcReg, isKill * RegState::Kill).addImm(ImmEnc)); 2796263509Sdim if (hasS) 2797263509Sdim AddDefaultCC(MIB); 2798263509Sdim // Second instruction consumes the first's result. 2799263509Sdim SrcReg = ResultReg; 2800223017Sdim } 2801223017Sdim 2802235633Sdim return ResultReg; 2803235633Sdim} 2804235633Sdim 2805235633Sdimbool ARMFastISel::SelectIntExt(const Instruction *I) { 2806235633Sdim // On ARM, in general, integer casts don't involve legal types; this code 2807235633Sdim // handles promotable integers. 2808235633Sdim Type *DestTy = I->getType(); 2809235633Sdim Value *Src = I->getOperand(0); 2810235633Sdim Type *SrcTy = Src->getType(); 2811235633Sdim 2812235633Sdim bool isZExt = isa<ZExtInst>(I); 2813235633Sdim unsigned SrcReg = getRegForValue(Src); 2814235633Sdim if (!SrcReg) return false; 2815235633Sdim 2816252723Sdim EVT SrcEVT, DestEVT; 2817252723Sdim SrcEVT = TLI.getValueType(SrcTy, true); 2818252723Sdim DestEVT = TLI.getValueType(DestTy, true); 2819252723Sdim if (!SrcEVT.isSimple()) return false; 2820252723Sdim if (!DestEVT.isSimple()) return false; 2821252723Sdim 2822252723Sdim MVT SrcVT = SrcEVT.getSimpleVT(); 2823252723Sdim MVT DestVT = DestEVT.getSimpleVT(); 2824235633Sdim unsigned ResultReg = ARMEmitIntExt(SrcVT, SrcReg, DestVT, isZExt); 2825235633Sdim if (ResultReg == 0) return false; 2826235633Sdim UpdateValueMap(I, ResultReg); 2827223017Sdim return true; 2828223017Sdim} 2829223017Sdim 2830245431Sdimbool ARMFastISel::SelectShift(const Instruction *I, 2831245431Sdim ARM_AM::ShiftOpc ShiftTy) { 2832245431Sdim // We handle thumb2 mode by target independent selector 2833245431Sdim // or SelectionDAG ISel. 2834245431Sdim if (isThumb2) 2835245431Sdim return false; 2836245431Sdim 2837245431Sdim // Only handle i32 now. 2838245431Sdim EVT DestVT = TLI.getValueType(I->getType(), true); 2839245431Sdim if (DestVT != MVT::i32) 2840245431Sdim return false; 2841245431Sdim 2842245431Sdim unsigned Opc = ARM::MOVsr; 2843245431Sdim unsigned ShiftImm; 2844245431Sdim Value *Src2Value = I->getOperand(1); 2845245431Sdim if (const ConstantInt *CI = dyn_cast<ConstantInt>(Src2Value)) { 2846245431Sdim ShiftImm = CI->getZExtValue(); 2847245431Sdim 2848245431Sdim // Fall back to selection DAG isel if the shift amount 2849245431Sdim // is zero or greater than the width of the value type. 2850245431Sdim if (ShiftImm == 0 || ShiftImm >=32) 2851245431Sdim return false; 2852245431Sdim 2853245431Sdim Opc = ARM::MOVsi; 2854245431Sdim } 2855245431Sdim 2856245431Sdim Value *Src1Value = I->getOperand(0); 2857245431Sdim unsigned Reg1 = getRegForValue(Src1Value); 2858245431Sdim if (Reg1 == 0) return false; 2859245431Sdim 2860245431Sdim unsigned Reg2 = 0; 2861245431Sdim if (Opc == ARM::MOVsr) { 2862245431Sdim Reg2 = getRegForValue(Src2Value); 2863245431Sdim if (Reg2 == 0) return false; 2864245431Sdim } 2865245431Sdim 2866263509Sdim unsigned ResultReg = createResultReg(&ARM::GPRnopcRegClass); 2867245431Sdim if(ResultReg == 0) return false; 2868245431Sdim 2869245431Sdim MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 2870245431Sdim TII.get(Opc), ResultReg) 2871245431Sdim .addReg(Reg1); 2872245431Sdim 2873245431Sdim if (Opc == ARM::MOVsi) 2874245431Sdim MIB.addImm(ARM_AM::getSORegOpc(ShiftTy, ShiftImm)); 2875245431Sdim else if (Opc == ARM::MOVsr) { 2876245431Sdim MIB.addReg(Reg2); 2877245431Sdim MIB.addImm(ARM_AM::getSORegOpc(ShiftTy, 0)); 2878245431Sdim } 2879245431Sdim 2880245431Sdim AddOptionalDefs(MIB); 2881245431Sdim UpdateValueMap(I, ResultReg); 2882245431Sdim return true; 2883245431Sdim} 2884245431Sdim 2885212793Sdim// TODO: SoftFP support. 2886212793Sdimbool ARMFastISel::TargetSelectInstruction(const Instruction *I) { 2887218893Sdim 2888212793Sdim switch (I->getOpcode()) { 2889212793Sdim case Instruction::Load: 2890218893Sdim return SelectLoad(I); 2891212793Sdim case Instruction::Store: 2892218893Sdim return SelectStore(I); 2893212793Sdim case Instruction::Br: 2894218893Sdim return SelectBranch(I); 2895235633Sdim case Instruction::IndirectBr: 2896235633Sdim return SelectIndirectBr(I); 2897218893Sdim case Instruction::ICmp: 2898218893Sdim case Instruction::FCmp: 2899218893Sdim return SelectCmp(I); 2900218893Sdim case Instruction::FPExt: 2901218893Sdim return SelectFPExt(I); 2902218893Sdim case Instruction::FPTrunc: 2903218893Sdim return SelectFPTrunc(I); 2904218893Sdim case Instruction::SIToFP: 2905235633Sdim return SelectIToFP(I, /*isSigned*/ true); 2906235633Sdim case Instruction::UIToFP: 2907235633Sdim return SelectIToFP(I, /*isSigned*/ false); 2908218893Sdim case Instruction::FPToSI: 2909235633Sdim return SelectFPToI(I, /*isSigned*/ true); 2910235633Sdim case Instruction::FPToUI: 2911235633Sdim return SelectFPToI(I, /*isSigned*/ false); 2912235633Sdim case Instruction::Add: 2913235633Sdim return SelectBinaryIntOp(I, ISD::ADD); 2914235633Sdim case Instruction::Or: 2915235633Sdim return SelectBinaryIntOp(I, ISD::OR); 2916235633Sdim case Instruction::Sub: 2917235633Sdim return SelectBinaryIntOp(I, ISD::SUB); 2918218893Sdim case Instruction::FAdd: 2919235633Sdim return SelectBinaryFPOp(I, ISD::FADD); 2920218893Sdim case Instruction::FSub: 2921235633Sdim return SelectBinaryFPOp(I, ISD::FSUB); 2922218893Sdim case Instruction::FMul: 2923235633Sdim return SelectBinaryFPOp(I, ISD::FMUL); 2924218893Sdim case Instruction::SDiv: 2925235633Sdim return SelectDiv(I, /*isSigned*/ true); 2926235633Sdim case Instruction::UDiv: 2927235633Sdim return SelectDiv(I, /*isSigned*/ false); 2928218893Sdim case Instruction::SRem: 2929235633Sdim return SelectRem(I, /*isSigned*/ true); 2930235633Sdim case Instruction::URem: 2931235633Sdim return SelectRem(I, /*isSigned*/ false); 2932218893Sdim case Instruction::Call: 2933235633Sdim if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) 2934235633Sdim return SelectIntrinsicCall(*II); 2935218893Sdim return SelectCall(I); 2936218893Sdim case Instruction::Select: 2937218893Sdim return SelectSelect(I); 2938218893Sdim case Instruction::Ret: 2939218893Sdim return SelectRet(I); 2940223017Sdim case Instruction::Trunc: 2941235633Sdim return SelectTrunc(I); 2942223017Sdim case Instruction::ZExt: 2943223017Sdim case Instruction::SExt: 2944235633Sdim return SelectIntExt(I); 2945245431Sdim case Instruction::Shl: 2946245431Sdim return SelectShift(I, ARM_AM::lsl); 2947245431Sdim case Instruction::LShr: 2948245431Sdim return SelectShift(I, ARM_AM::lsr); 2949245431Sdim case Instruction::AShr: 2950245431Sdim return SelectShift(I, ARM_AM::asr); 2951212793Sdim default: break; 2952212793Sdim } 2953212793Sdim return false; 2954212793Sdim} 2955212793Sdim 2956263509Sdimnamespace { 2957263509Sdim// This table describes sign- and zero-extend instructions which can be 2958263509Sdim// folded into a preceding load. All of these extends have an immediate 2959263509Sdim// (sometimes a mask and sometimes a shift) that's applied after 2960263509Sdim// extension. 2961263509Sdimconst struct FoldableLoadExtendsStruct { 2962263509Sdim uint16_t Opc[2]; // ARM, Thumb. 2963263509Sdim uint8_t ExpectedImm; 2964263509Sdim uint8_t isZExt : 1; 2965263509Sdim uint8_t ExpectedVT : 7; 2966263509Sdim} FoldableLoadExtends[] = { 2967263509Sdim { { ARM::SXTH, ARM::t2SXTH }, 0, 0, MVT::i16 }, 2968263509Sdim { { ARM::UXTH, ARM::t2UXTH }, 0, 1, MVT::i16 }, 2969263509Sdim { { ARM::ANDri, ARM::t2ANDri }, 255, 1, MVT::i8 }, 2970263509Sdim { { ARM::SXTB, ARM::t2SXTB }, 0, 0, MVT::i8 }, 2971263509Sdim { { ARM::UXTB, ARM::t2UXTB }, 0, 1, MVT::i8 } 2972263509Sdim}; 2973263509Sdim} 2974263509Sdim 2975252723Sdim/// \brief The specified machine instr operand is a vreg, and that 2976235633Sdim/// vreg is being provided by the specified load instruction. If possible, 2977235633Sdim/// try to fold the load as an operand to the instruction, returning true if 2978235633Sdim/// successful. 2979252723Sdimbool ARMFastISel::tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo, 2980252723Sdim const LoadInst *LI) { 2981235633Sdim // Verify we have a legal type before going any further. 2982235633Sdim MVT VT; 2983235633Sdim if (!isLoadTypeLegal(LI->getType(), VT)) 2984235633Sdim return false; 2985235633Sdim 2986235633Sdim // Combine load followed by zero- or sign-extend. 2987235633Sdim // ldrb r1, [r0] ldrb r1, [r0] 2988235633Sdim // uxtb r2, r1 => 2989235633Sdim // mov r3, r2 mov r3, r1 2990263509Sdim if (MI->getNumOperands() < 3 || !MI->getOperand(2).isImm()) 2991263509Sdim return false; 2992263509Sdim const uint64_t Imm = MI->getOperand(2).getImm(); 2993263509Sdim 2994263509Sdim bool Found = false; 2995263509Sdim bool isZExt; 2996263509Sdim for (unsigned i = 0, e = array_lengthof(FoldableLoadExtends); 2997263509Sdim i != e; ++i) { 2998263509Sdim if (FoldableLoadExtends[i].Opc[isThumb2] == MI->getOpcode() && 2999263509Sdim (uint64_t)FoldableLoadExtends[i].ExpectedImm == Imm && 3000263509Sdim MVT((MVT::SimpleValueType)FoldableLoadExtends[i].ExpectedVT) == VT) { 3001263509Sdim Found = true; 3002263509Sdim isZExt = FoldableLoadExtends[i].isZExt; 3003263509Sdim } 3004235633Sdim } 3005263509Sdim if (!Found) return false; 3006263509Sdim 3007235633Sdim // See if we can handle this address. 3008235633Sdim Address Addr; 3009235633Sdim if (!ARMComputeAddress(LI->getOperand(0), Addr)) return false; 3010245431Sdim 3011235633Sdim unsigned ResultReg = MI->getOperand(0).getReg(); 3012235633Sdim if (!ARMEmitLoad(VT, ResultReg, Addr, LI->getAlignment(), isZExt, false)) 3013235633Sdim return false; 3014235633Sdim MI->eraseFromParent(); 3015235633Sdim return true; 3016235633Sdim} 3017235633Sdim 3018245431Sdimunsigned ARMFastISel::ARMLowerPICELF(const GlobalValue *GV, 3019252723Sdim unsigned Align, MVT VT) { 3020245431Sdim bool UseGOTOFF = GV->hasLocalLinkage() || GV->hasHiddenVisibility(); 3021245431Sdim ARMConstantPoolConstant *CPV = 3022245431Sdim ARMConstantPoolConstant::Create(GV, UseGOTOFF ? ARMCP::GOTOFF : ARMCP::GOT); 3023245431Sdim unsigned Idx = MCP.getConstantPoolIndex(CPV, Align); 3024245431Sdim 3025245431Sdim unsigned Opc; 3026245431Sdim unsigned DestReg1 = createResultReg(TLI.getRegClassFor(VT)); 3027245431Sdim // Load value. 3028245431Sdim if (isThumb2) { 3029263509Sdim DestReg1 = constrainOperandRegClass(TII.get(ARM::t2LDRpci), DestReg1, 0); 3030245431Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 3031245431Sdim TII.get(ARM::t2LDRpci), DestReg1) 3032245431Sdim .addConstantPoolIndex(Idx)); 3033245431Sdim Opc = UseGOTOFF ? ARM::t2ADDrr : ARM::t2LDRs; 3034245431Sdim } else { 3035245431Sdim // The extra immediate is for addrmode2. 3036263509Sdim DestReg1 = constrainOperandRegClass(TII.get(ARM::LDRcp), DestReg1, 0); 3037245431Sdim AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, 3038245431Sdim DL, TII.get(ARM::LDRcp), DestReg1) 3039245431Sdim .addConstantPoolIndex(Idx).addImm(0)); 3040245431Sdim Opc = UseGOTOFF ? ARM::ADDrr : ARM::LDRrs; 3041245431Sdim } 3042245431Sdim 3043245431Sdim unsigned GlobalBaseReg = AFI->getGlobalBaseReg(); 3044245431Sdim if (GlobalBaseReg == 0) { 3045245431Sdim GlobalBaseReg = MRI.createVirtualRegister(TLI.getRegClassFor(VT)); 3046245431Sdim AFI->setGlobalBaseReg(GlobalBaseReg); 3047245431Sdim } 3048245431Sdim 3049245431Sdim unsigned DestReg2 = createResultReg(TLI.getRegClassFor(VT)); 3050263509Sdim DestReg2 = constrainOperandRegClass(TII.get(Opc), DestReg2, 0); 3051263509Sdim DestReg1 = constrainOperandRegClass(TII.get(Opc), DestReg1, 1); 3052263509Sdim GlobalBaseReg = constrainOperandRegClass(TII.get(Opc), GlobalBaseReg, 2); 3053245431Sdim MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, 3054245431Sdim DL, TII.get(Opc), DestReg2) 3055245431Sdim .addReg(DestReg1) 3056245431Sdim .addReg(GlobalBaseReg); 3057245431Sdim if (!UseGOTOFF) 3058245431Sdim MIB.addImm(0); 3059245431Sdim AddOptionalDefs(MIB); 3060245431Sdim 3061245431Sdim return DestReg2; 3062245431Sdim} 3063245431Sdim 3064252723Sdimbool ARMFastISel::FastLowerArguments() { 3065252723Sdim if (!FuncInfo.CanLowerReturn) 3066252723Sdim return false; 3067252723Sdim 3068252723Sdim const Function *F = FuncInfo.Fn; 3069252723Sdim if (F->isVarArg()) 3070252723Sdim return false; 3071252723Sdim 3072252723Sdim CallingConv::ID CC = F->getCallingConv(); 3073252723Sdim switch (CC) { 3074252723Sdim default: 3075252723Sdim return false; 3076252723Sdim case CallingConv::Fast: 3077252723Sdim case CallingConv::C: 3078252723Sdim case CallingConv::ARM_AAPCS_VFP: 3079252723Sdim case CallingConv::ARM_AAPCS: 3080252723Sdim case CallingConv::ARM_APCS: 3081252723Sdim break; 3082252723Sdim } 3083252723Sdim 3084252723Sdim // Only handle simple cases. i.e. Up to 4 i8/i16/i32 scalar arguments 3085252723Sdim // which are passed in r0 - r3. 3086252723Sdim unsigned Idx = 1; 3087252723Sdim for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); 3088252723Sdim I != E; ++I, ++Idx) { 3089252723Sdim if (Idx > 4) 3090252723Sdim return false; 3091252723Sdim 3092252723Sdim if (F->getAttributes().hasAttribute(Idx, Attribute::InReg) || 3093252723Sdim F->getAttributes().hasAttribute(Idx, Attribute::StructRet) || 3094252723Sdim F->getAttributes().hasAttribute(Idx, Attribute::ByVal)) 3095252723Sdim return false; 3096252723Sdim 3097252723Sdim Type *ArgTy = I->getType(); 3098252723Sdim if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy()) 3099252723Sdim return false; 3100252723Sdim 3101252723Sdim EVT ArgVT = TLI.getValueType(ArgTy); 3102252723Sdim if (!ArgVT.isSimple()) return false; 3103252723Sdim switch (ArgVT.getSimpleVT().SimpleTy) { 3104252723Sdim case MVT::i8: 3105252723Sdim case MVT::i16: 3106252723Sdim case MVT::i32: 3107252723Sdim break; 3108252723Sdim default: 3109252723Sdim return false; 3110252723Sdim } 3111252723Sdim } 3112252723Sdim 3113252723Sdim 3114252723Sdim static const uint16_t GPRArgRegs[] = { 3115252723Sdim ARM::R0, ARM::R1, ARM::R2, ARM::R3 3116252723Sdim }; 3117252723Sdim 3118263509Sdim const TargetRegisterClass *RC = &ARM::rGPRRegClass; 3119252723Sdim Idx = 0; 3120252723Sdim for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); 3121252723Sdim I != E; ++I, ++Idx) { 3122252723Sdim unsigned SrcReg = GPRArgRegs[Idx]; 3123252723Sdim unsigned DstReg = FuncInfo.MF->addLiveIn(SrcReg, RC); 3124252723Sdim // FIXME: Unfortunately it's necessary to emit a copy from the livein copy. 3125252723Sdim // Without this, EmitLiveInCopies may eliminate the livein if its only 3126252723Sdim // use is a bitcast (which isn't turned into an instruction). 3127252723Sdim unsigned ResultReg = createResultReg(RC); 3128252723Sdim BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), 3129252723Sdim ResultReg).addReg(DstReg, getKillRegState(true)); 3130252723Sdim UpdateValueMap(I, ResultReg); 3131252723Sdim } 3132252723Sdim 3133252723Sdim return true; 3134252723Sdim} 3135252723Sdim 3136212793Sdimnamespace llvm { 3137245431Sdim FastISel *ARM::createFastISel(FunctionLoweringInfo &funcInfo, 3138245431Sdim const TargetLibraryInfo *libInfo) { 3139218893Sdim const TargetMachine &TM = funcInfo.MF->getTarget(); 3140218893Sdim 3141218893Sdim const ARMSubtarget *Subtarget = &TM.getSubtarget<ARMSubtarget>(); 3142263509Sdim // Thumb2 support on iOS; ARM support on iOS, Linux and NaCl. 3143263509Sdim bool UseFastISel = false; 3144263509Sdim UseFastISel |= Subtarget->isTargetIOS() && !Subtarget->isThumb1Only(); 3145263509Sdim UseFastISel |= Subtarget->isTargetLinux() && !Subtarget->isThumb(); 3146263509Sdim UseFastISel |= Subtarget->isTargetNaCl() && !Subtarget->isThumb(); 3147263509Sdim 3148263509Sdim if (UseFastISel) { 3149263509Sdim // iOS always has a FP for backtracking, force other targets 3150263509Sdim // to keep their FP when doing FastISel. The emitted code is 3151263509Sdim // currently superior, and in cases like test-suite's lencod 3152263509Sdim // FastISel isn't quite correct when FP is eliminated. 3153263509Sdim TM.Options.NoFramePointerElim = true; 3154245431Sdim return new ARMFastISel(funcInfo, libInfo); 3155263509Sdim } 3156212793Sdim return 0; 3157212793Sdim } 3158212793Sdim} 3159