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