MipsISelLowering.h revision 7d71209912bb55856f34df7013382e6dd310983b
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//===-- MipsISelLowering.h - Mips DAG Lowering Interface --------*- C++ -*-===//
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// License. See LICENSE.TXT for details.
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//===----------------------------------------------------------------------===//
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This file defines the interfaces that Mips uses to lower LLVM code into a
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// selection DAG.
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//===----------------------------------------------------------------------===//
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifndef MipsISELLOWERING_H
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define MipsISELLOWERING_H
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "Mips.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "MipsSubtarget.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/CodeGen/CallingConvLower.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/CodeGen/SelectionDAG.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/Target/TargetLowering.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace llvm {
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  namespace MipsISD {
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    enum NodeType {
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Start the numbering from where ISD NodeType finishes.
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FIRST_NUMBER = ISD::BUILTIN_OP_END,
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Jump and link (call)
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      JmpLink,
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Tail call
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      TailCall,
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Get the Higher 16 bits from a 32-bit immediate
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // No relation with Mips Hi register
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Hi,
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Get the Lower 16 bits from a 32-bit immediate
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // No relation with Mips Lo register
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Lo,
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Handle gp_rel (small data/bss sections) relocation.
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GPRel,
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Thread Pointer
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ThreadPointer,
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Floating Point Branch Conditional
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FPBrcond,
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Floating Point Compare
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FPCmp,
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Floating Point Conditional Moves
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CMovFP_T,
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CMovFP_F,
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Floating Point Rounding
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FPRound,
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Return
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Ret,
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // MAdd/Sub nodes
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      MAdd,
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      MAddu,
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      MSub,
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      MSubu,
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // DivRem(u)
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DivRem,
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DivRemU,
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
76      BuildPairF64,
77      ExtractElementF64,
78
79      Wrapper,
80
81      DynAlloc,
82
83      Sync,
84
85      Ext,
86      Ins,
87
88      // EXTR.W instrinsic nodes.
89      EXTP,
90      EXTPDP,
91      EXTR_S_H,
92      EXTR_W,
93      EXTR_R_W,
94      EXTR_RS_W,
95      SHILO,
96      MTHLIP,
97
98      // DPA.W intrinsic nodes.
99      MULSAQ_S_W_PH,
100      MAQ_S_W_PHL,
101      MAQ_S_W_PHR,
102      MAQ_SA_W_PHL,
103      MAQ_SA_W_PHR,
104      DPAU_H_QBL,
105      DPAU_H_QBR,
106      DPSU_H_QBL,
107      DPSU_H_QBR,
108      DPAQ_S_W_PH,
109      DPSQ_S_W_PH,
110      DPAQ_SA_L_W,
111      DPSQ_SA_L_W,
112      DPA_W_PH,
113      DPS_W_PH,
114      DPAQX_S_W_PH,
115      DPAQX_SA_W_PH,
116      DPAX_W_PH,
117      DPSX_W_PH,
118      DPSQX_S_W_PH,
119      DPSQX_SA_W_PH,
120      MULSA_W_PH,
121
122      MULT,
123      MULTU,
124      MADD_DSP,
125      MADDU_DSP,
126      MSUB_DSP,
127      MSUBU_DSP,
128
129      // Load/Store Left/Right nodes.
130      LWL = ISD::FIRST_TARGET_MEMORY_OPCODE,
131      LWR,
132      SWL,
133      SWR,
134      LDL,
135      LDR,
136      SDL,
137      SDR
138    };
139  }
140
141  //===--------------------------------------------------------------------===//
142  // TargetLowering Implementation
143  //===--------------------------------------------------------------------===//
144
145  class MipsTargetLowering : public TargetLowering  {
146  public:
147    explicit MipsTargetLowering(MipsTargetMachine &TM);
148
149    virtual MVT getShiftAmountTy(EVT LHSTy) const { return MVT::i32; }
150
151    virtual bool allowsUnalignedMemoryAccesses (EVT VT) const;
152
153    virtual void LowerOperationWrapper(SDNode *N,
154                                       SmallVectorImpl<SDValue> &Results,
155                                       SelectionDAG &DAG) const;
156
157    /// LowerOperation - Provide custom lowering hooks for some operations.
158    virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
159
160    /// ReplaceNodeResults - Replace the results of node with an illegal result
161    /// type with new values built out of custom code.
162    ///
163    virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,
164                                    SelectionDAG &DAG) const;
165
166    /// getTargetNodeName - This method returns the name of a target specific
167    //  DAG node.
168    virtual const char *getTargetNodeName(unsigned Opcode) const;
169
170    /// getSetCCResultType - get the ISD::SETCC result ValueType
171    EVT getSetCCResultType(EVT VT) const;
172
173    virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
174  private:
175
176    /// ByValArgInfo - Byval argument information.
177    struct ByValArgInfo {
178      unsigned FirstIdx; // Index of the first register used.
179      unsigned NumRegs;  // Number of registers used for this argument.
180      unsigned Address;  // Offset of the stack area used to pass this argument.
181
182      ByValArgInfo() : FirstIdx(0), NumRegs(0), Address(0) {}
183    };
184
185    /// MipsCC - This class provides methods used to analyze formal and call
186    /// arguments and inquire about calling convention information.
187    class MipsCC {
188    public:
189      MipsCC(CallingConv::ID CallConv, bool IsVarArg, bool IsO32,
190             CCState &Info);
191
192      void analyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs);
193      void analyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins);
194      void handleByValArg(unsigned ValNo, MVT ValVT, MVT LocVT,
195                          CCValAssign::LocInfo LocInfo,
196                          ISD::ArgFlagsTy ArgFlags);
197
198      const CCState &getCCInfo() const { return CCInfo; }
199
200      /// hasByValArg - Returns true if function has byval arguments.
201      bool hasByValArg() const { return !ByValArgs.empty(); }
202
203      /// useRegsForByval - Returns true if the calling convention allows the
204      /// use of registers to pass byval arguments.
205      bool useRegsForByval() const { return UseRegsForByval; }
206
207      /// regSize - Size (in number of bits) of integer registers.
208      unsigned regSize() const { return RegSize; }
209
210      /// numIntArgRegs - Number of integer registers available for calls.
211      unsigned numIntArgRegs() const { return NumIntArgRegs; }
212
213      /// reservedArgArea - The size of the area the caller reserves for
214      /// register arguments. This is 16-byte if ABI is O32.
215      unsigned reservedArgArea() const { return ReservedArgArea; }
216
217      /// intArgRegs - Pointer to array of integer registers.
218      const uint16_t *intArgRegs() const { return IntArgRegs; }
219
220      typedef SmallVector<ByValArgInfo, 2>::const_iterator byval_iterator;
221      byval_iterator byval_begin() const { return ByValArgs.begin(); }
222      byval_iterator byval_end() const { return ByValArgs.end(); }
223
224    private:
225      void allocateRegs(ByValArgInfo &ByVal, unsigned ByValSize,
226                        unsigned Align);
227
228      CCState &CCInfo;
229      bool UseRegsForByval;
230      unsigned RegSize;
231      unsigned NumIntArgRegs;
232      unsigned ReservedArgArea;
233      const uint16_t *IntArgRegs, *ShadowRegs;
234      SmallVector<ByValArgInfo, 2> ByValArgs;
235      llvm::CCAssignFn *FixedFn, *VarFn;
236    };
237
238    // Subtarget Info
239    const MipsSubtarget *Subtarget;
240
241    bool HasMips64, IsN64, IsO32;
242
243    // Lower Operand helpers
244    SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
245                            CallingConv::ID CallConv, bool isVarArg,
246                            const SmallVectorImpl<ISD::InputArg> &Ins,
247                            DebugLoc dl, SelectionDAG &DAG,
248                            SmallVectorImpl<SDValue> &InVals) const;
249
250    // Lower Operand specifics
251    SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
252    SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
253    SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
254    SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
255    SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
256    SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
257    SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const;
258    SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
259    SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
260    SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
261    SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const;
262    SDValue LowerFABS(SDValue Op, SelectionDAG &DAG) const;
263    SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
264    SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
265    SDValue LowerMEMBARRIER(SDValue Op, SelectionDAG& DAG) const;
266    SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
267    SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG& DAG) const;
268    SDValue LowerShiftRightParts(SDValue Op, SelectionDAG& DAG,
269                                 bool IsSRA) const;
270    SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
271    SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const;
272    SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
273    SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const;
274
275    /// IsEligibleForTailCallOptimization - Check whether the call is eligible
276    /// for tail call optimization.
277    bool IsEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
278                                           bool IsVarArg,
279                                           unsigned NextStackOffset) const;
280
281    /// copyByValArg - Copy argument registers which were used to pass a byval
282    /// argument to the stack. Create a stack frame object for the byval
283    /// argument.
284    void copyByValRegs(SDValue Chain, DebugLoc DL,
285                       std::vector<SDValue> &OutChains, SelectionDAG &DAG,
286                       const ISD::ArgFlagsTy &Flags,
287                       SmallVectorImpl<SDValue> &InVals,
288                       const Argument *FuncArg,
289                       const MipsCC &CC, const ByValArgInfo &ByVal) const;
290
291    /// passByValArg - Pass a byval argument in registers or on stack.
292    void passByValArg(SDValue Chain, DebugLoc DL,
293                      SmallVector<std::pair<unsigned, SDValue>, 16> &RegsToPass,
294                      SmallVector<SDValue, 8> &MemOpChains, SDValue StackPtr,
295                      MachineFrameInfo *MFI, SelectionDAG &DAG, SDValue Arg,
296                      const MipsCC &CC, const ByValArgInfo &ByVal,
297                      const ISD::ArgFlagsTy &Flags, bool isLittle) const;
298
299    /// writeVarArgRegs - Write variable function arguments passed in registers
300    /// to the stack. Also create a stack frame object for the first variable
301    /// argument.
302    void writeVarArgRegs(std::vector<SDValue> &OutChains, const MipsCC &CC,
303                         SDValue Chain, DebugLoc DL, SelectionDAG &DAG) const;
304
305    virtual SDValue
306      LowerFormalArguments(SDValue Chain,
307                           CallingConv::ID CallConv, bool isVarArg,
308                           const SmallVectorImpl<ISD::InputArg> &Ins,
309                           DebugLoc dl, SelectionDAG &DAG,
310                           SmallVectorImpl<SDValue> &InVals) const;
311
312    SDValue passArgOnStack(SDValue StackPtr, unsigned Offset, SDValue Chain,
313                           SDValue Arg, DebugLoc DL, bool IsTailCall,
314                           SelectionDAG &DAG) const;
315
316    virtual SDValue
317      LowerCall(TargetLowering::CallLoweringInfo &CLI,
318                SmallVectorImpl<SDValue> &InVals) const;
319
320    virtual bool
321      CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
322                     bool isVarArg,
323                     const SmallVectorImpl<ISD::OutputArg> &Outs,
324                     LLVMContext &Context) const;
325
326    virtual SDValue
327      LowerReturn(SDValue Chain,
328                  CallingConv::ID CallConv, bool isVarArg,
329                  const SmallVectorImpl<ISD::OutputArg> &Outs,
330                  const SmallVectorImpl<SDValue> &OutVals,
331                  DebugLoc dl, SelectionDAG &DAG) const;
332
333    virtual MachineBasicBlock *
334      EmitInstrWithCustomInserter(MachineInstr *MI,
335                                  MachineBasicBlock *MBB) const;
336
337    // Inline asm support
338    ConstraintType getConstraintType(const std::string &Constraint) const;
339
340    /// Examine constraint string and operand type and determine a weight value.
341    /// The operand object must already have been set up with the operand type.
342    ConstraintWeight getSingleConstraintMatchWeight(
343      AsmOperandInfo &info, const char *constraint) const;
344
345    std::pair<unsigned, const TargetRegisterClass*>
346              getRegForInlineAsmConstraint(const std::string &Constraint,
347              EVT VT) const;
348
349    /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
350    /// vector.  If it is invalid, don't add anything to Ops. If hasMemory is
351    /// true it means one of the asm constraint of the inline asm instruction
352    /// being processed is 'm'.
353    virtual void LowerAsmOperandForConstraint(SDValue Op,
354                                              std::string &Constraint,
355                                              std::vector<SDValue> &Ops,
356                                              SelectionDAG &DAG) const;
357
358    virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
359
360    virtual EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
361                                    unsigned SrcAlign, bool IsZeroVal,
362                                    bool MemcpyStrSrc,
363                                    MachineFunction &MF) const;
364
365    /// isFPImmLegal - Returns true if the target can instruction select the
366    /// specified FP immediate natively. If false, the legalizer will
367    /// materialize the FP immediate as a load from a constant pool.
368    virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const;
369
370    virtual unsigned getJumpTableEncoding() const;
371
372    MachineBasicBlock *EmitBPOSGE32(MachineInstr *MI,
373                                    MachineBasicBlock *BB) const;
374    MachineBasicBlock *EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB,
375                    unsigned Size, unsigned BinOpcode, bool Nand = false) const;
376    MachineBasicBlock *EmitAtomicBinaryPartword(MachineInstr *MI,
377                    MachineBasicBlock *BB, unsigned Size, unsigned BinOpcode,
378                    bool Nand = false) const;
379    MachineBasicBlock *EmitAtomicCmpSwap(MachineInstr *MI,
380                                  MachineBasicBlock *BB, unsigned Size) const;
381    MachineBasicBlock *EmitAtomicCmpSwapPartword(MachineInstr *MI,
382                                  MachineBasicBlock *BB, unsigned Size) const;
383  };
384}
385
386#endif // MipsISELLOWERING_H
387