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