1193323Sed//===-- MipsISelLowering.h - Mips DAG Lowering Interface --------*- C++ -*-===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file defines the interfaces that Mips uses to lower LLVM code into a 11193323Sed// selection DAG. 12193323Sed// 13193323Sed//===----------------------------------------------------------------------===// 14193323Sed 15193323Sed#ifndef MipsISELLOWERING_H 16193323Sed#define MipsISELLOWERING_H 17193323Sed 18234353Sdim#include "Mips.h" 19234353Sdim#include "MipsSubtarget.h" 20263508Sdim#include "MCTargetDesc/MipsBaseInfo.h" 21243830Sdim#include "llvm/CodeGen/CallingConvLower.h" 22193323Sed#include "llvm/CodeGen/SelectionDAG.h" 23249423Sdim#include "llvm/IR/Function.h" 24193323Sed#include "llvm/Target/TargetLowering.h" 25249423Sdim#include <deque> 26249423Sdim#include <string> 27193323Sed 28193323Sednamespace llvm { 29193323Sed namespace MipsISD { 30193323Sed enum NodeType { 31193323Sed // Start the numbering from where ISD NodeType finishes. 32193323Sed FIRST_NUMBER = ISD::BUILTIN_OP_END, 33193323Sed 34193323Sed // Jump and link (call) 35193323Sed JmpLink, 36193323Sed 37243830Sdim // Tail call 38243830Sdim TailCall, 39243830Sdim 40193323Sed // Get the Higher 16 bits from a 32-bit immediate 41193323Sed // No relation with Mips Hi register 42221345Sdim Hi, 43193323Sed 44193323Sed // Get the Lower 16 bits from a 32-bit immediate 45193323Sed // No relation with Mips Lo register 46221345Sdim Lo, 47193323Sed 48193323Sed // Handle gp_rel (small data/bss sections) relocation. 49193323Sed GPRel, 50193323Sed 51223017Sdim // Thread Pointer 52223017Sdim ThreadPointer, 53223017Sdim 54193323Sed // Floating Point Branch Conditional 55193323Sed FPBrcond, 56193323Sed 57193323Sed // Floating Point Compare 58193323Sed FPCmp, 59193323Sed 60221345Sdim // Floating Point Conditional Moves 61221345Sdim CMovFP_T, 62221345Sdim CMovFP_F, 63221345Sdim 64263508Sdim // FP-to-int truncation node. 65263508Sdim TruncIntFP, 66193323Sed 67221345Sdim // Return 68218893Sdim Ret, 69218893Sdim 70249423Sdim EH_RETURN, 71249423Sdim 72249423Sdim // Node used to extract integer from accumulator. 73263508Sdim MFHI, 74263508Sdim MFLO, 75249423Sdim 76249423Sdim // Node used to insert integers to accumulator. 77263508Sdim MTLOHI, 78249423Sdim 79249423Sdim // Mult nodes. 80249423Sdim Mult, 81249423Sdim Multu, 82249423Sdim 83218893Sdim // MAdd/Sub nodes 84218893Sdim MAdd, 85218893Sdim MAddu, 86218893Sdim MSub, 87221345Sdim MSubu, 88221345Sdim 89221345Sdim // DivRem(u) 90221345Sdim DivRem, 91221345Sdim DivRemU, 92249423Sdim DivRem16, 93249423Sdim DivRemU16, 94221345Sdim 95221345Sdim BuildPairF64, 96223017Sdim ExtractElementF64, 97223017Sdim 98234353Sdim Wrapper, 99224145Sdim 100226633Sdim DynAlloc, 101226633Sdim 102226633Sdim Sync, 103226633Sdim 104226633Sdim Ext, 105239462Sdim Ins, 106239462Sdim 107243830Sdim // EXTR.W instrinsic nodes. 108243830Sdim EXTP, 109243830Sdim EXTPDP, 110243830Sdim EXTR_S_H, 111243830Sdim EXTR_W, 112243830Sdim EXTR_R_W, 113243830Sdim EXTR_RS_W, 114243830Sdim SHILO, 115243830Sdim MTHLIP, 116243830Sdim 117243830Sdim // DPA.W intrinsic nodes. 118243830Sdim MULSAQ_S_W_PH, 119243830Sdim MAQ_S_W_PHL, 120243830Sdim MAQ_S_W_PHR, 121243830Sdim MAQ_SA_W_PHL, 122243830Sdim MAQ_SA_W_PHR, 123243830Sdim DPAU_H_QBL, 124243830Sdim DPAU_H_QBR, 125243830Sdim DPSU_H_QBL, 126243830Sdim DPSU_H_QBR, 127243830Sdim DPAQ_S_W_PH, 128243830Sdim DPSQ_S_W_PH, 129243830Sdim DPAQ_SA_L_W, 130243830Sdim DPSQ_SA_L_W, 131243830Sdim DPA_W_PH, 132243830Sdim DPS_W_PH, 133243830Sdim DPAQX_S_W_PH, 134243830Sdim DPAQX_SA_W_PH, 135243830Sdim DPAX_W_PH, 136243830Sdim DPSX_W_PH, 137243830Sdim DPSQX_S_W_PH, 138243830Sdim DPSQX_SA_W_PH, 139243830Sdim MULSA_W_PH, 140243830Sdim 141243830Sdim MULT, 142243830Sdim MULTU, 143243830Sdim MADD_DSP, 144243830Sdim MADDU_DSP, 145243830Sdim MSUB_DSP, 146243830Sdim MSUBU_DSP, 147243830Sdim 148251662Sdim // DSP shift nodes. 149251662Sdim SHLL_DSP, 150251662Sdim SHRA_DSP, 151251662Sdim SHRL_DSP, 152251662Sdim 153251662Sdim // DSP setcc and select_cc nodes. 154251662Sdim SETCC_DSP, 155251662Sdim SELECT_CC_DSP, 156251662Sdim 157263508Sdim // Vector comparisons. 158263508Sdim // These take a vector and return a boolean. 159263508Sdim VALL_ZERO, 160263508Sdim VANY_ZERO, 161263508Sdim VALL_NONZERO, 162263508Sdim VANY_NONZERO, 163263508Sdim 164263508Sdim // These take a vector and return a vector bitmask. 165263508Sdim VCEQ, 166263508Sdim VCLE_S, 167263508Sdim VCLE_U, 168263508Sdim VCLT_S, 169263508Sdim VCLT_U, 170263508Sdim 171263508Sdim // Element-wise vector max/min. 172263508Sdim VSMAX, 173263508Sdim VSMIN, 174263508Sdim VUMAX, 175263508Sdim VUMIN, 176263508Sdim 177263508Sdim // Vector Shuffle with mask as an operand 178263508Sdim VSHF, // Generic shuffle 179263508Sdim SHF, // 4-element set shuffle. 180263508Sdim ILVEV, // Interleave even elements 181263508Sdim ILVOD, // Interleave odd elements 182263508Sdim ILVL, // Interleave left elements 183263508Sdim ILVR, // Interleave right elements 184263508Sdim PCKEV, // Pack even elements 185263508Sdim PCKOD, // Pack odd elements 186263508Sdim 187263508Sdim // Combined (XOR (OR $a, $b), -1) 188263508Sdim VNOR, 189263508Sdim 190263508Sdim // Extended vector element extraction 191263508Sdim VEXTRACT_SEXT_ELT, 192263508Sdim VEXTRACT_ZEXT_ELT, 193263508Sdim 194239462Sdim // Load/Store Left/Right nodes. 195239462Sdim LWL = ISD::FIRST_TARGET_MEMORY_OPCODE, 196239462Sdim LWR, 197239462Sdim SWL, 198239462Sdim SWR, 199239462Sdim LDL, 200239462Sdim LDR, 201239462Sdim SDL, 202239462Sdim SDR 203193323Sed }; 204193323Sed } 205193323Sed 206193323Sed //===--------------------------------------------------------------------===// 207193323Sed // TargetLowering Implementation 208193323Sed //===--------------------------------------------------------------------===// 209243830Sdim class MipsFunctionInfo; 210221345Sdim 211198090Srdivacky class MipsTargetLowering : public TargetLowering { 212193323Sed public: 213193323Sed explicit MipsTargetLowering(MipsTargetMachine &TM); 214193323Sed 215249423Sdim static const MipsTargetLowering *create(MipsTargetMachine &TM); 216234353Sdim 217249423Sdim virtual MVT getScalarShiftAmountTy(EVT LHSTy) const { return MVT::i32; } 218226633Sdim 219243830Sdim virtual void LowerOperationWrapper(SDNode *N, 220243830Sdim SmallVectorImpl<SDValue> &Results, 221243830Sdim SelectionDAG &DAG) const; 222243830Sdim 223193323Sed /// LowerOperation - Provide custom lowering hooks for some operations. 224207618Srdivacky virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const; 225193323Sed 226243830Sdim /// ReplaceNodeResults - Replace the results of node with an illegal result 227243830Sdim /// type with new values built out of custom code. 228243830Sdim /// 229243830Sdim virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results, 230243830Sdim SelectionDAG &DAG) const; 231243830Sdim 232221345Sdim /// getTargetNodeName - This method returns the name of a target specific 233193323Sed // DAG node. 234193323Sed virtual const char *getTargetNodeName(unsigned Opcode) const; 235193323Sed 236193323Sed /// getSetCCResultType - get the ISD::SETCC result ValueType 237263508Sdim EVT getSetCCResultType(LLVMContext &Context, EVT VT) const; 238193323Sed 239221345Sdim virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; 240243830Sdim 241249423Sdim virtual MachineBasicBlock * 242249423Sdim EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const; 243249423Sdim 244249423Sdim struct LTStr { 245249423Sdim bool operator()(const char *S1, const char *S2) const { 246249423Sdim return strcmp(S1, S2) < 0; 247249423Sdim } 248249423Sdim }; 249249423Sdim 250249423Sdim protected: 251249423Sdim SDValue getGlobalReg(SelectionDAG &DAG, EVT Ty) const; 252249423Sdim 253263508Sdim // This method creates the following nodes, which are necessary for 254263508Sdim // computing a local symbol's address: 255263508Sdim // 256263508Sdim // (add (load (wrapper $gp, %got(sym)), %lo(sym)) 257263508Sdim template<class NodeTy> 258263508Sdim SDValue getAddrLocal(NodeTy *N, EVT Ty, SelectionDAG &DAG, 259263508Sdim bool HasMips64) const { 260263508Sdim SDLoc DL(N); 261263508Sdim unsigned GOTFlag = HasMips64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT; 262263508Sdim SDValue GOT = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty), 263263508Sdim getTargetNode(N, Ty, DAG, GOTFlag)); 264263508Sdim SDValue Load = DAG.getLoad(Ty, DL, DAG.getEntryNode(), GOT, 265263508Sdim MachinePointerInfo::getGOT(), false, false, 266263508Sdim false, 0); 267263508Sdim unsigned LoFlag = HasMips64 ? MipsII::MO_GOT_OFST : MipsII::MO_ABS_LO; 268263508Sdim SDValue Lo = DAG.getNode(MipsISD::Lo, DL, Ty, 269263508Sdim getTargetNode(N, Ty, DAG, LoFlag)); 270263508Sdim return DAG.getNode(ISD::ADD, DL, Ty, Load, Lo); 271263508Sdim } 272249423Sdim 273263508Sdim // This method creates the following nodes, which are necessary for 274263508Sdim // computing a global symbol's address: 275263508Sdim // 276263508Sdim // (load (wrapper $gp, %got(sym))) 277263508Sdim template<class NodeTy> 278263508Sdim SDValue getAddrGlobal(NodeTy *N, EVT Ty, SelectionDAG &DAG, 279263508Sdim unsigned Flag, SDValue Chain, 280263508Sdim const MachinePointerInfo &PtrInfo) const { 281263508Sdim SDLoc DL(N); 282263508Sdim SDValue Tgt = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty), 283263508Sdim getTargetNode(N, Ty, DAG, Flag)); 284263508Sdim return DAG.getLoad(Ty, DL, Chain, Tgt, PtrInfo, false, false, false, 0); 285263508Sdim } 286249423Sdim 287263508Sdim // This method creates the following nodes, which are necessary for 288263508Sdim // computing a global symbol's address in large-GOT mode: 289263508Sdim // 290263508Sdim // (load (wrapper (add %hi(sym), $gp), %lo(sym))) 291263508Sdim template<class NodeTy> 292263508Sdim SDValue getAddrGlobalLargeGOT(NodeTy *N, EVT Ty, SelectionDAG &DAG, 293263508Sdim unsigned HiFlag, unsigned LoFlag, 294263508Sdim SDValue Chain, 295263508Sdim const MachinePointerInfo &PtrInfo) const { 296263508Sdim SDLoc DL(N); 297263508Sdim SDValue Hi = DAG.getNode(MipsISD::Hi, DL, Ty, 298263508Sdim getTargetNode(N, Ty, DAG, HiFlag)); 299263508Sdim Hi = DAG.getNode(ISD::ADD, DL, Ty, Hi, getGlobalReg(DAG, Ty)); 300263508Sdim SDValue Wrapper = DAG.getNode(MipsISD::Wrapper, DL, Ty, Hi, 301263508Sdim getTargetNode(N, Ty, DAG, LoFlag)); 302263508Sdim return DAG.getLoad(Ty, DL, Chain, Wrapper, PtrInfo, false, false, false, 303263508Sdim 0); 304263508Sdim } 305249423Sdim 306263508Sdim // This method creates the following nodes, which are necessary for 307263508Sdim // computing a symbol's address in non-PIC mode: 308263508Sdim // 309263508Sdim // (add %hi(sym), %lo(sym)) 310263508Sdim template<class NodeTy> 311263508Sdim SDValue getAddrNonPIC(NodeTy *N, EVT Ty, SelectionDAG &DAG) const { 312263508Sdim SDLoc DL(N); 313263508Sdim SDValue Hi = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI); 314263508Sdim SDValue Lo = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO); 315263508Sdim return DAG.getNode(ISD::ADD, DL, Ty, 316263508Sdim DAG.getNode(MipsISD::Hi, DL, Ty, Hi), 317263508Sdim DAG.getNode(MipsISD::Lo, DL, Ty, Lo)); 318263508Sdim } 319263508Sdim 320249423Sdim /// This function fills Ops, which is the list of operands that will later 321249423Sdim /// be used when a function call node is created. It also generates 322249423Sdim /// copyToReg nodes to set up argument registers. 323249423Sdim virtual void 324249423Sdim getOpndList(SmallVectorImpl<SDValue> &Ops, 325249423Sdim std::deque< std::pair<unsigned, SDValue> > &RegsToPass, 326249423Sdim bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, 327249423Sdim CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const; 328249423Sdim 329243830Sdim /// ByValArgInfo - Byval argument information. 330243830Sdim struct ByValArgInfo { 331243830Sdim unsigned FirstIdx; // Index of the first register used. 332243830Sdim unsigned NumRegs; // Number of registers used for this argument. 333243830Sdim unsigned Address; // Offset of the stack area used to pass this argument. 334243830Sdim 335243830Sdim ByValArgInfo() : FirstIdx(0), NumRegs(0), Address(0) {} 336243830Sdim }; 337243830Sdim 338243830Sdim /// MipsCC - This class provides methods used to analyze formal and call 339243830Sdim /// arguments and inquire about calling convention information. 340243830Sdim class MipsCC { 341243830Sdim public: 342263508Sdim enum SpecialCallingConvType { 343263508Sdim Mips16RetHelperConv, NoSpecialCallingConv 344263508Sdim }; 345243830Sdim 346263508Sdim MipsCC(CallingConv::ID CallConv, bool IsO32, bool IsFP64, CCState &Info, 347263508Sdim SpecialCallingConvType SpecialCallingConv = NoSpecialCallingConv); 348263508Sdim 349263508Sdim 350249423Sdim void analyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, 351249423Sdim bool IsVarArg, bool IsSoftFloat, 352249423Sdim const SDNode *CallNode, 353249423Sdim std::vector<ArgListEntry> &FuncArgs); 354249423Sdim void analyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins, 355249423Sdim bool IsSoftFloat, 356249423Sdim Function::const_arg_iterator FuncArg); 357243830Sdim 358249423Sdim void analyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins, 359249423Sdim bool IsSoftFloat, const SDNode *CallNode, 360249423Sdim const Type *RetTy) const; 361249423Sdim 362249423Sdim void analyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, 363249423Sdim bool IsSoftFloat, const Type *RetTy) const; 364249423Sdim 365243830Sdim const CCState &getCCInfo() const { return CCInfo; } 366243830Sdim 367243830Sdim /// hasByValArg - Returns true if function has byval arguments. 368243830Sdim bool hasByValArg() const { return !ByValArgs.empty(); } 369243830Sdim 370243830Sdim /// regSize - Size (in number of bits) of integer registers. 371249423Sdim unsigned regSize() const { return IsO32 ? 4 : 8; } 372243830Sdim 373243830Sdim /// numIntArgRegs - Number of integer registers available for calls. 374249423Sdim unsigned numIntArgRegs() const; 375243830Sdim 376243830Sdim /// reservedArgArea - The size of the area the caller reserves for 377243830Sdim /// register arguments. This is 16-byte if ABI is O32. 378249423Sdim unsigned reservedArgArea() const; 379243830Sdim 380249423Sdim /// Return pointer to array of integer argument registers. 381249423Sdim const uint16_t *intArgRegs() const; 382243830Sdim 383263508Sdim typedef SmallVectorImpl<ByValArgInfo>::const_iterator byval_iterator; 384243830Sdim byval_iterator byval_begin() const { return ByValArgs.begin(); } 385243830Sdim byval_iterator byval_end() const { return ByValArgs.end(); } 386243830Sdim 387243830Sdim private: 388249423Sdim void handleByValArg(unsigned ValNo, MVT ValVT, MVT LocVT, 389249423Sdim CCValAssign::LocInfo LocInfo, 390249423Sdim ISD::ArgFlagsTy ArgFlags); 391249423Sdim 392249423Sdim /// useRegsForByval - Returns true if the calling convention allows the 393249423Sdim /// use of registers to pass byval arguments. 394249423Sdim bool useRegsForByval() const { return CallConv != CallingConv::Fast; } 395249423Sdim 396249423Sdim /// Return the function that analyzes fixed argument list functions. 397249423Sdim llvm::CCAssignFn *fixedArgFn() const; 398249423Sdim 399249423Sdim /// Return the function that analyzes variable argument list functions. 400249423Sdim llvm::CCAssignFn *varArgFn() const; 401249423Sdim 402249423Sdim const uint16_t *shadowRegs() const; 403249423Sdim 404243830Sdim void allocateRegs(ByValArgInfo &ByVal, unsigned ByValSize, 405243830Sdim unsigned Align); 406243830Sdim 407249423Sdim /// Return the type of the register which is used to pass an argument or 408249423Sdim /// return a value. This function returns f64 if the argument is an i64 409249423Sdim /// value which has been generated as a result of softening an f128 value. 410249423Sdim /// Otherwise, it just returns VT. 411249423Sdim MVT getRegVT(MVT VT, const Type *OrigTy, const SDNode *CallNode, 412249423Sdim bool IsSoftFloat) const; 413249423Sdim 414249423Sdim template<typename Ty> 415249423Sdim void analyzeReturn(const SmallVectorImpl<Ty> &RetVals, bool IsSoftFloat, 416249423Sdim const SDNode *CallNode, const Type *RetTy) const; 417249423Sdim 418243830Sdim CCState &CCInfo; 419249423Sdim CallingConv::ID CallConv; 420263508Sdim bool IsO32, IsFP64; 421263508Sdim SpecialCallingConvType SpecialCallingConv; 422243830Sdim SmallVector<ByValArgInfo, 2> ByValArgs; 423243830Sdim }; 424263508Sdim protected: 425263508Sdim SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const; 426263508Sdim SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const; 427243830Sdim 428193323Sed // Subtarget Info 429193323Sed const MipsSubtarget *Subtarget; 430193323Sed 431234353Sdim bool HasMips64, IsN64, IsO32; 432234353Sdim 433249423Sdim private: 434263508Sdim // Create a TargetGlobalAddress node. 435263508Sdim SDValue getTargetNode(GlobalAddressSDNode *N, EVT Ty, SelectionDAG &DAG, 436263508Sdim unsigned Flag) const; 437263508Sdim 438263508Sdim // Create a TargetExternalSymbol node. 439263508Sdim SDValue getTargetNode(ExternalSymbolSDNode *N, EVT Ty, SelectionDAG &DAG, 440263508Sdim unsigned Flag) const; 441263508Sdim 442263508Sdim // Create a TargetBlockAddress node. 443263508Sdim SDValue getTargetNode(BlockAddressSDNode *N, EVT Ty, SelectionDAG &DAG, 444263508Sdim unsigned Flag) const; 445263508Sdim 446263508Sdim // Create a TargetJumpTable node. 447263508Sdim SDValue getTargetNode(JumpTableSDNode *N, EVT Ty, SelectionDAG &DAG, 448263508Sdim unsigned Flag) const; 449263508Sdim 450263508Sdim // Create a TargetConstantPool node. 451263508Sdim SDValue getTargetNode(ConstantPoolSDNode *N, EVT Ty, SelectionDAG &DAG, 452263508Sdim unsigned Flag) const; 453263508Sdim 454263508Sdim MipsCC::SpecialCallingConvType getSpecialCallingConv(SDValue Callee) const; 455193323Sed // Lower Operand helpers 456198090Srdivacky SDValue LowerCallResult(SDValue Chain, SDValue InFlag, 457198090Srdivacky CallingConv::ID CallConv, bool isVarArg, 458198090Srdivacky const SmallVectorImpl<ISD::InputArg> &Ins, 459263508Sdim SDLoc dl, SelectionDAG &DAG, 460249423Sdim SmallVectorImpl<SDValue> &InVals, 461249423Sdim const SDNode *CallNode, const Type *RetTy) const; 462193323Sed 463193323Sed // Lower Operand specifics 464249423Sdim SDValue lowerBR_JT(SDValue Op, SelectionDAG &DAG) const; 465249423Sdim SDValue lowerBRCOND(SDValue Op, SelectionDAG &DAG) const; 466249423Sdim SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 467249423Sdim SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 468249423Sdim SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 469249423Sdim SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 470249423Sdim SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const; 471249423Sdim SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const; 472249423Sdim SDValue lowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; 473249423Sdim SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const; 474249423Sdim SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const; 475249423Sdim SDValue lowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const; 476249423Sdim SDValue lowerFABS(SDValue Op, SelectionDAG &DAG) const; 477249423Sdim SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; 478249423Sdim SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; 479249423Sdim SDValue lowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const; 480249423Sdim SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const; 481249423Sdim SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG& DAG) const; 482249423Sdim SDValue lowerShiftRightParts(SDValue Op, SelectionDAG& DAG, 483239462Sdim bool IsSRA) const; 484249423Sdim SDValue lowerADD(SDValue Op, SelectionDAG &DAG) const; 485263508Sdim SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const; 486193323Sed 487249423Sdim /// isEligibleForTailCallOptimization - Check whether the call is eligible 488243830Sdim /// for tail call optimization. 489249423Sdim virtual bool 490249423Sdim isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo, 491249423Sdim unsigned NextStackOffset, 492249423Sdim const MipsFunctionInfo& FI) const = 0; 493243830Sdim 494243830Sdim /// copyByValArg - Copy argument registers which were used to pass a byval 495243830Sdim /// argument to the stack. Create a stack frame object for the byval 496243830Sdim /// argument. 497263508Sdim void copyByValRegs(SDValue Chain, SDLoc DL, 498243830Sdim std::vector<SDValue> &OutChains, SelectionDAG &DAG, 499243830Sdim const ISD::ArgFlagsTy &Flags, 500243830Sdim SmallVectorImpl<SDValue> &InVals, 501243830Sdim const Argument *FuncArg, 502243830Sdim const MipsCC &CC, const ByValArgInfo &ByVal) const; 503243830Sdim 504243830Sdim /// passByValArg - Pass a byval argument in registers or on stack. 505263508Sdim void passByValArg(SDValue Chain, SDLoc DL, 506249423Sdim std::deque< std::pair<unsigned, SDValue> > &RegsToPass, 507263508Sdim SmallVectorImpl<SDValue> &MemOpChains, SDValue StackPtr, 508243830Sdim MachineFrameInfo *MFI, SelectionDAG &DAG, SDValue Arg, 509243830Sdim const MipsCC &CC, const ByValArgInfo &ByVal, 510243830Sdim const ISD::ArgFlagsTy &Flags, bool isLittle) const; 511243830Sdim 512243830Sdim /// writeVarArgRegs - Write variable function arguments passed in registers 513243830Sdim /// to the stack. Also create a stack frame object for the first variable 514243830Sdim /// argument. 515243830Sdim void writeVarArgRegs(std::vector<SDValue> &OutChains, const MipsCC &CC, 516263508Sdim SDValue Chain, SDLoc DL, SelectionDAG &DAG) const; 517243830Sdim 518198090Srdivacky virtual SDValue 519198090Srdivacky LowerFormalArguments(SDValue Chain, 520198090Srdivacky CallingConv::ID CallConv, bool isVarArg, 521198090Srdivacky const SmallVectorImpl<ISD::InputArg> &Ins, 522263508Sdim SDLoc dl, SelectionDAG &DAG, 523207618Srdivacky SmallVectorImpl<SDValue> &InVals) const; 524198090Srdivacky 525243830Sdim SDValue passArgOnStack(SDValue StackPtr, unsigned Offset, SDValue Chain, 526263508Sdim SDValue Arg, SDLoc DL, bool IsTailCall, 527243830Sdim SelectionDAG &DAG) const; 528243830Sdim 529198090Srdivacky virtual SDValue 530239462Sdim LowerCall(TargetLowering::CallLoweringInfo &CLI, 531207618Srdivacky SmallVectorImpl<SDValue> &InVals) const; 532198090Srdivacky 533243830Sdim virtual bool 534243830Sdim CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 535243830Sdim bool isVarArg, 536243830Sdim const SmallVectorImpl<ISD::OutputArg> &Outs, 537243830Sdim LLVMContext &Context) const; 538243830Sdim 539198090Srdivacky virtual SDValue 540198090Srdivacky LowerReturn(SDValue Chain, 541198090Srdivacky CallingConv::ID CallConv, bool isVarArg, 542198090Srdivacky const SmallVectorImpl<ISD::OutputArg> &Outs, 543210299Sed const SmallVectorImpl<SDValue> &OutVals, 544263508Sdim SDLoc dl, SelectionDAG &DAG) const; 545198090Srdivacky 546193323Sed // Inline asm support 547193323Sed ConstraintType getConstraintType(const std::string &Constraint) const; 548193323Sed 549218893Sdim /// Examine constraint string and operand type and determine a weight value. 550218893Sdim /// The operand object must already have been set up with the operand type. 551218893Sdim ConstraintWeight getSingleConstraintMatchWeight( 552218893Sdim AsmOperandInfo &info, const char *constraint) const; 553218893Sdim 554263508Sdim /// This function parses registers that appear in inline-asm constraints. 555263508Sdim /// It returns pair (0, 0) on failure. 556263508Sdim std::pair<unsigned, const TargetRegisterClass *> 557263508Sdim parseRegForInlineAsmConstraint(const StringRef &C, MVT VT) const; 558263508Sdim 559221345Sdim std::pair<unsigned, const TargetRegisterClass*> 560193323Sed getRegForInlineAsmConstraint(const std::string &Constraint, 561263508Sdim MVT VT) const; 562193323Sed 563239462Sdim /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops 564239462Sdim /// vector. If it is invalid, don't add anything to Ops. If hasMemory is 565239462Sdim /// true it means one of the asm constraint of the inline asm instruction 566239462Sdim /// being processed is 'm'. 567239462Sdim virtual void LowerAsmOperandForConstraint(SDValue Op, 568239462Sdim std::string &Constraint, 569239462Sdim std::vector<SDValue> &Ops, 570239462Sdim SelectionDAG &DAG) const; 571239462Sdim 572249423Sdim virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const; 573249423Sdim 574193323Sed virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const; 575198892Srdivacky 576239462Sdim virtual EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign, 577249423Sdim unsigned SrcAlign, 578249423Sdim bool IsMemset, bool ZeroMemset, 579239462Sdim bool MemcpyStrSrc, 580239462Sdim MachineFunction &MF) const; 581239462Sdim 582198892Srdivacky /// isFPImmLegal - Returns true if the target can instruction select the 583198892Srdivacky /// specified FP immediate natively. If false, the legalizer will 584198892Srdivacky /// materialize the FP immediate as a load from a constant pool. 585198892Srdivacky virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const; 586223017Sdim 587234353Sdim virtual unsigned getJumpTableEncoding() const; 588234353Sdim 589249423Sdim MachineBasicBlock *emitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, 590223017Sdim unsigned Size, unsigned BinOpcode, bool Nand = false) const; 591249423Sdim MachineBasicBlock *emitAtomicBinaryPartword(MachineInstr *MI, 592223017Sdim MachineBasicBlock *BB, unsigned Size, unsigned BinOpcode, 593223017Sdim bool Nand = false) const; 594249423Sdim MachineBasicBlock *emitAtomicCmpSwap(MachineInstr *MI, 595223017Sdim MachineBasicBlock *BB, unsigned Size) const; 596249423Sdim MachineBasicBlock *emitAtomicCmpSwapPartword(MachineInstr *MI, 597223017Sdim MachineBasicBlock *BB, unsigned Size) const; 598193323Sed }; 599249423Sdim 600249423Sdim /// Create MipsTargetLowering objects. 601249423Sdim const MipsTargetLowering *createMips16TargetLowering(MipsTargetMachine &TM); 602249423Sdim const MipsTargetLowering *createMipsSETargetLowering(MipsTargetMachine &TM); 603193323Sed} 604193323Sed 605193323Sed#endif // MipsISELLOWERING_H 606