xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Mips/MipsISelLowering.h (revision 924226fba12cc9a228c73b956e1b7fa24c60b055)
1 //===- MipsISelLowering.h - Mips DAG Lowering Interface ---------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the interfaces that Mips uses to lower LLVM code into a
10 // selection DAG.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_LIB_TARGET_MIPS_MIPSISELLOWERING_H
15 #define LLVM_LIB_TARGET_MIPS_MIPSISELLOWERING_H
16 
17 #include "MCTargetDesc/MipsABIInfo.h"
18 #include "MCTargetDesc/MipsBaseInfo.h"
19 #include "MCTargetDesc/MipsMCTargetDesc.h"
20 #include "Mips.h"
21 #include "llvm/CodeGen/CallingConvLower.h"
22 #include "llvm/CodeGen/ISDOpcodes.h"
23 #include "llvm/CodeGen/MachineMemOperand.h"
24 #include "llvm/CodeGen/SelectionDAG.h"
25 #include "llvm/CodeGen/SelectionDAGNodes.h"
26 #include "llvm/CodeGen/TargetLowering.h"
27 #include "llvm/CodeGen/ValueTypes.h"
28 #include "llvm/IR/CallingConv.h"
29 #include "llvm/IR/InlineAsm.h"
30 #include "llvm/IR/Type.h"
31 #include "llvm/Support/MachineValueType.h"
32 #include "llvm/Target/TargetMachine.h"
33 #include <algorithm>
34 #include <cassert>
35 #include <deque>
36 #include <string>
37 #include <utility>
38 #include <vector>
39 
40 namespace llvm {
41 
42 class Argument;
43 class FastISel;
44 class FunctionLoweringInfo;
45 class MachineBasicBlock;
46 class MachineFrameInfo;
47 class MachineInstr;
48 class MipsCCState;
49 class MipsFunctionInfo;
50 class MipsSubtarget;
51 class MipsTargetMachine;
52 class TargetLibraryInfo;
53 class TargetRegisterClass;
54 
55   namespace MipsISD {
56 
57     enum NodeType : unsigned {
58       // Start the numbering from where ISD NodeType finishes.
59       FIRST_NUMBER = ISD::BUILTIN_OP_END,
60 
61       // Jump and link (call)
62       JmpLink,
63 
64       // Tail call
65       TailCall,
66 
67       // Get the Highest (63-48) 16 bits from a 64-bit immediate
68       Highest,
69 
70       // Get the Higher (47-32) 16 bits from a 64-bit immediate
71       Higher,
72 
73       // Get the High 16 bits from a 32/64-bit immediate
74       // No relation with Mips Hi register
75       Hi,
76 
77       // Get the Lower 16 bits from a 32/64-bit immediate
78       // No relation with Mips Lo register
79       Lo,
80 
81       // Get the High 16 bits from a 32 bit immediate for accessing the GOT.
82       GotHi,
83 
84       // Get the High 16 bits from a 32-bit immediate for accessing TLS.
85       TlsHi,
86 
87       // Handle gp_rel (small data/bss sections) relocation.
88       GPRel,
89 
90       // Thread Pointer
91       ThreadPointer,
92 
93       // Vector Floating Point Multiply and Subtract
94       FMS,
95 
96       // Floating Point Branch Conditional
97       FPBrcond,
98 
99       // Floating Point Compare
100       FPCmp,
101 
102       // Floating point Abs
103       FAbs,
104 
105       // Floating point select
106       FSELECT,
107 
108       // Node used to generate an MTC1 i32 to f64 instruction
109       MTC1_D64,
110 
111       // Floating Point Conditional Moves
112       CMovFP_T,
113       CMovFP_F,
114 
115       // FP-to-int truncation node.
116       TruncIntFP,
117 
118       // Return
119       Ret,
120 
121       // Interrupt, exception, error trap Return
122       ERet,
123 
124       // Software Exception Return.
125       EH_RETURN,
126 
127       // Node used to extract integer from accumulator.
128       MFHI,
129       MFLO,
130 
131       // Node used to insert integers to accumulator.
132       MTLOHI,
133 
134       // Mult nodes.
135       Mult,
136       Multu,
137 
138       // MAdd/Sub nodes
139       MAdd,
140       MAddu,
141       MSub,
142       MSubu,
143 
144       // DivRem(u)
145       DivRem,
146       DivRemU,
147       DivRem16,
148       DivRemU16,
149 
150       BuildPairF64,
151       ExtractElementF64,
152 
153       Wrapper,
154 
155       DynAlloc,
156 
157       Sync,
158 
159       Ext,
160       Ins,
161       CIns,
162 
163       // EXTR.W instrinsic nodes.
164       EXTP,
165       EXTPDP,
166       EXTR_S_H,
167       EXTR_W,
168       EXTR_R_W,
169       EXTR_RS_W,
170       SHILO,
171       MTHLIP,
172 
173       // DPA.W intrinsic nodes.
174       MULSAQ_S_W_PH,
175       MAQ_S_W_PHL,
176       MAQ_S_W_PHR,
177       MAQ_SA_W_PHL,
178       MAQ_SA_W_PHR,
179       DPAU_H_QBL,
180       DPAU_H_QBR,
181       DPSU_H_QBL,
182       DPSU_H_QBR,
183       DPAQ_S_W_PH,
184       DPSQ_S_W_PH,
185       DPAQ_SA_L_W,
186       DPSQ_SA_L_W,
187       DPA_W_PH,
188       DPS_W_PH,
189       DPAQX_S_W_PH,
190       DPAQX_SA_W_PH,
191       DPAX_W_PH,
192       DPSX_W_PH,
193       DPSQX_S_W_PH,
194       DPSQX_SA_W_PH,
195       MULSA_W_PH,
196 
197       MULT,
198       MULTU,
199       MADD_DSP,
200       MADDU_DSP,
201       MSUB_DSP,
202       MSUBU_DSP,
203 
204       // DSP shift nodes.
205       SHLL_DSP,
206       SHRA_DSP,
207       SHRL_DSP,
208 
209       // DSP setcc and select_cc nodes.
210       SETCC_DSP,
211       SELECT_CC_DSP,
212 
213       // Vector comparisons.
214       // These take a vector and return a boolean.
215       VALL_ZERO,
216       VANY_ZERO,
217       VALL_NONZERO,
218       VANY_NONZERO,
219 
220       // These take a vector and return a vector bitmask.
221       VCEQ,
222       VCLE_S,
223       VCLE_U,
224       VCLT_S,
225       VCLT_U,
226 
227       // Vector Shuffle with mask as an operand
228       VSHF,  // Generic shuffle
229       SHF,   // 4-element set shuffle.
230       ILVEV, // Interleave even elements
231       ILVOD, // Interleave odd elements
232       ILVL,  // Interleave left elements
233       ILVR,  // Interleave right elements
234       PCKEV, // Pack even elements
235       PCKOD, // Pack odd elements
236 
237       // Vector Lane Copy
238       INSVE, // Copy element from one vector to another
239 
240       // Combined (XOR (OR $a, $b), -1)
241       VNOR,
242 
243       // Extended vector element extraction
244       VEXTRACT_SEXT_ELT,
245       VEXTRACT_ZEXT_ELT,
246 
247       // Load/Store Left/Right nodes.
248       LWL = ISD::FIRST_TARGET_MEMORY_OPCODE,
249       LWR,
250       SWL,
251       SWR,
252       LDL,
253       LDR,
254       SDL,
255       SDR
256     };
257 
258   } // ene namespace MipsISD
259 
260   //===--------------------------------------------------------------------===//
261   // TargetLowering Implementation
262   //===--------------------------------------------------------------------===//
263 
264   class MipsTargetLowering : public TargetLowering  {
265     bool isMicroMips;
266 
267   public:
268     explicit MipsTargetLowering(const MipsTargetMachine &TM,
269                                 const MipsSubtarget &STI);
270 
271     static const MipsTargetLowering *create(const MipsTargetMachine &TM,
272                                             const MipsSubtarget &STI);
273 
274     /// createFastISel - This method returns a target specific FastISel object,
275     /// or null if the target does not support "fast" ISel.
276     FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
277                              const TargetLibraryInfo *libInfo) const override;
278 
279     MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override {
280       return MVT::i32;
281     }
282 
283     EVT getTypeForExtReturn(LLVMContext &Context, EVT VT,
284                             ISD::NodeType) const override;
285 
286     bool isCheapToSpeculateCttz() const override;
287     bool isCheapToSpeculateCtlz() const override;
288     bool shouldFoldConstantShiftPairToMask(const SDNode *N,
289                                            CombineLevel Level) const override;
290 
291     /// Return the register type for a given MVT, ensuring vectors are treated
292     /// as a series of gpr sized integers.
293     MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC,
294                                       EVT VT) const override;
295 
296     /// Return the number of registers for a given MVT, ensuring vectors are
297     /// treated as a series of gpr sized integers.
298     unsigned getNumRegistersForCallingConv(LLVMContext &Context,
299                                            CallingConv::ID CC,
300                                            EVT VT) const override;
301 
302     /// Break down vectors to the correct number of gpr sized integers.
303     unsigned getVectorTypeBreakdownForCallingConv(
304         LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT,
305         unsigned &NumIntermediates, MVT &RegisterVT) const override;
306 
307     /// Return the correct alignment for the current calling convention.
308     Align getABIAlignmentForCallingConv(Type *ArgTy,
309                                         const DataLayout &DL) const override {
310       const Align ABIAlign = DL.getABITypeAlign(ArgTy);
311       if (ArgTy->isVectorTy())
312         return std::min(ABIAlign, Align(8));
313       return ABIAlign;
314     }
315 
316     ISD::NodeType getExtendForAtomicOps() const override {
317       return ISD::SIGN_EXTEND;
318     }
319 
320     /// LowerOperation - Provide custom lowering hooks for some operations.
321     SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
322 
323     /// ReplaceNodeResults - Replace the results of node with an illegal result
324     /// type with new values built out of custom code.
325     ///
326     void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,
327                             SelectionDAG &DAG) const override;
328 
329     /// getTargetNodeName - This method returns the name of a target specific
330     //  DAG node.
331     const char *getTargetNodeName(unsigned Opcode) const override;
332 
333     /// getSetCCResultType - get the ISD::SETCC result ValueType
334     EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
335                            EVT VT) const override;
336 
337     SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
338 
339     MachineBasicBlock *
340     EmitInstrWithCustomInserter(MachineInstr &MI,
341                                 MachineBasicBlock *MBB) const override;
342 
343     void AdjustInstrPostInstrSelection(MachineInstr &MI,
344                                        SDNode *Node) const override;
345 
346     void HandleByVal(CCState *, unsigned &, Align) const override;
347 
348     Register getRegisterByName(const char* RegName, LLT VT,
349                                const MachineFunction &MF) const override;
350 
351     /// If a physical register, this returns the register that receives the
352     /// exception address on entry to an EH pad.
353     Register
354     getExceptionPointerRegister(const Constant *PersonalityFn) const override {
355       return ABI.IsN64() ? Mips::A0_64 : Mips::A0;
356     }
357 
358     /// If a physical register, this returns the register that receives the
359     /// exception typeid on entry to a landing pad.
360     Register
361     getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
362       return ABI.IsN64() ? Mips::A1_64 : Mips::A1;
363     }
364 
365     bool isJumpTableRelative() const override {
366       return getTargetMachine().isPositionIndependent();
367     }
368 
369    CCAssignFn *CCAssignFnForCall() const;
370 
371    CCAssignFn *CCAssignFnForReturn() const;
372 
373   protected:
374     SDValue getGlobalReg(SelectionDAG &DAG, EVT Ty) const;
375 
376     // This method creates the following nodes, which are necessary for
377     // computing a local symbol's address:
378     //
379     // (add (load (wrapper $gp, %got(sym)), %lo(sym))
380     template <class NodeTy>
381     SDValue getAddrLocal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG,
382                          bool IsN32OrN64) const {
383       unsigned GOTFlag = IsN32OrN64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT;
384       SDValue GOT = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty),
385                                 getTargetNode(N, Ty, DAG, GOTFlag));
386       SDValue Load =
387           DAG.getLoad(Ty, DL, DAG.getEntryNode(), GOT,
388                       MachinePointerInfo::getGOT(DAG.getMachineFunction()));
389       unsigned LoFlag = IsN32OrN64 ? MipsII::MO_GOT_OFST : MipsII::MO_ABS_LO;
390       SDValue Lo = DAG.getNode(MipsISD::Lo, DL, Ty,
391                                getTargetNode(N, Ty, DAG, LoFlag));
392       return DAG.getNode(ISD::ADD, DL, Ty, Load, Lo);
393     }
394 
395     // This method creates the following nodes, which are necessary for
396     // computing a global symbol's address:
397     //
398     // (load (wrapper $gp, %got(sym)))
399     template <class NodeTy>
400     SDValue getAddrGlobal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG,
401                           unsigned Flag, SDValue Chain,
402                           const MachinePointerInfo &PtrInfo) const {
403       SDValue Tgt = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty),
404                                 getTargetNode(N, Ty, DAG, Flag));
405       return DAG.getLoad(Ty, DL, Chain, Tgt, PtrInfo);
406     }
407 
408     // This method creates the following nodes, which are necessary for
409     // computing a global symbol's address in large-GOT mode:
410     //
411     // (load (wrapper (add %hi(sym), $gp), %lo(sym)))
412     template <class NodeTy>
413     SDValue getAddrGlobalLargeGOT(NodeTy *N, const SDLoc &DL, EVT Ty,
414                                   SelectionDAG &DAG, unsigned HiFlag,
415                                   unsigned LoFlag, SDValue Chain,
416                                   const MachinePointerInfo &PtrInfo) const {
417       SDValue Hi = DAG.getNode(MipsISD::GotHi, DL, Ty,
418                                getTargetNode(N, Ty, DAG, HiFlag));
419       Hi = DAG.getNode(ISD::ADD, DL, Ty, Hi, getGlobalReg(DAG, Ty));
420       SDValue Wrapper = DAG.getNode(MipsISD::Wrapper, DL, Ty, Hi,
421                                     getTargetNode(N, Ty, DAG, LoFlag));
422       return DAG.getLoad(Ty, DL, Chain, Wrapper, PtrInfo);
423     }
424 
425     // This method creates the following nodes, which are necessary for
426     // computing a symbol's address in non-PIC mode:
427     //
428     // (add %hi(sym), %lo(sym))
429     //
430     // This method covers O32, N32 and N64 in sym32 mode.
431     template <class NodeTy>
432     SDValue getAddrNonPIC(NodeTy *N, const SDLoc &DL, EVT Ty,
433                           SelectionDAG &DAG) const {
434       SDValue Hi = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI);
435       SDValue Lo = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO);
436       return DAG.getNode(ISD::ADD, DL, Ty,
437                          DAG.getNode(MipsISD::Hi, DL, Ty, Hi),
438                          DAG.getNode(MipsISD::Lo, DL, Ty, Lo));
439    }
440 
441    // This method creates the following nodes, which are necessary for
442    // computing a symbol's address in non-PIC mode for N64.
443    //
444    // (add (shl (add (shl (add %highest(sym), %higher(sim)), 16), %high(sym)),
445    //            16), %lo(%sym))
446    //
447    // FIXME: This method is not efficent for (micro)MIPS64R6.
448    template <class NodeTy>
449    SDValue getAddrNonPICSym64(NodeTy *N, const SDLoc &DL, EVT Ty,
450                           SelectionDAG &DAG) const {
451       SDValue Hi = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI);
452       SDValue Lo = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO);
453 
454       SDValue Highest =
455           DAG.getNode(MipsISD::Highest, DL, Ty,
456                       getTargetNode(N, Ty, DAG, MipsII::MO_HIGHEST));
457       SDValue Higher = getTargetNode(N, Ty, DAG, MipsII::MO_HIGHER);
458       SDValue HigherPart =
459           DAG.getNode(ISD::ADD, DL, Ty, Highest,
460                       DAG.getNode(MipsISD::Higher, DL, Ty, Higher));
461       SDValue Cst = DAG.getConstant(16, DL, MVT::i32);
462       SDValue Shift = DAG.getNode(ISD::SHL, DL, Ty, HigherPart, Cst);
463       SDValue Add = DAG.getNode(ISD::ADD, DL, Ty, Shift,
464                                 DAG.getNode(MipsISD::Hi, DL, Ty, Hi));
465       SDValue Shift2 = DAG.getNode(ISD::SHL, DL, Ty, Add, Cst);
466 
467       return DAG.getNode(ISD::ADD, DL, Ty, Shift2,
468                          DAG.getNode(MipsISD::Lo, DL, Ty, Lo));
469    }
470 
471     // This method creates the following nodes, which are necessary for
472     // computing a symbol's address using gp-relative addressing:
473     //
474     // (add $gp, %gp_rel(sym))
475     template <class NodeTy>
476     SDValue getAddrGPRel(NodeTy *N, const SDLoc &DL, EVT Ty,
477                          SelectionDAG &DAG, bool IsN64) const {
478       SDValue GPRel = getTargetNode(N, Ty, DAG, MipsII::MO_GPREL);
479       return DAG.getNode(
480           ISD::ADD, DL, Ty,
481           DAG.getRegister(IsN64 ? Mips::GP_64 : Mips::GP, Ty),
482           DAG.getNode(MipsISD::GPRel, DL, DAG.getVTList(Ty), GPRel));
483     }
484 
485     /// This function fills Ops, which is the list of operands that will later
486     /// be used when a function call node is created. It also generates
487     /// copyToReg nodes to set up argument registers.
488     virtual void
489     getOpndList(SmallVectorImpl<SDValue> &Ops,
490                 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
491                 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
492                 bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
493                 SDValue Chain) const;
494 
495   protected:
496     SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const;
497     SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const;
498 
499     // Subtarget Info
500     const MipsSubtarget &Subtarget;
501     // Cache the ABI from the TargetMachine, we use it everywhere.
502     const MipsABIInfo &ABI;
503 
504   private:
505     // Create a TargetGlobalAddress node.
506     SDValue getTargetNode(GlobalAddressSDNode *N, EVT Ty, SelectionDAG &DAG,
507                           unsigned Flag) const;
508 
509     // Create a TargetExternalSymbol node.
510     SDValue getTargetNode(ExternalSymbolSDNode *N, EVT Ty, SelectionDAG &DAG,
511                           unsigned Flag) const;
512 
513     // Create a TargetBlockAddress node.
514     SDValue getTargetNode(BlockAddressSDNode *N, EVT Ty, SelectionDAG &DAG,
515                           unsigned Flag) const;
516 
517     // Create a TargetJumpTable node.
518     SDValue getTargetNode(JumpTableSDNode *N, EVT Ty, SelectionDAG &DAG,
519                           unsigned Flag) const;
520 
521     // Create a TargetConstantPool node.
522     SDValue getTargetNode(ConstantPoolSDNode *N, EVT Ty, SelectionDAG &DAG,
523                           unsigned Flag) const;
524 
525     // Lower Operand helpers
526     SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
527                             CallingConv::ID CallConv, bool isVarArg,
528                             const SmallVectorImpl<ISD::InputArg> &Ins,
529                             const SDLoc &dl, SelectionDAG &DAG,
530                             SmallVectorImpl<SDValue> &InVals,
531                             TargetLowering::CallLoweringInfo &CLI) const;
532 
533     // Lower Operand specifics
534     SDValue lowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
535     SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
536     SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
537     SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
538     SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
539     SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
540     SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const;
541     SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const;
542     SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
543     SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const;
544     SDValue lowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const;
545     SDValue lowerFABS(SDValue Op, SelectionDAG &DAG) const;
546     SDValue lowerFABS32(SDValue Op, SelectionDAG &DAG,
547                         bool HasExtractInsert) const;
548     SDValue lowerFABS64(SDValue Op, SelectionDAG &DAG,
549                         bool HasExtractInsert) const;
550     SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
551     SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
552     SDValue lowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
553     SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
554     SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG& DAG) const;
555     SDValue lowerShiftRightParts(SDValue Op, SelectionDAG& DAG,
556                                  bool IsSRA) const;
557     SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const;
558     SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const;
559 
560     /// isEligibleForTailCallOptimization - Check whether the call is eligible
561     /// for tail call optimization.
562     virtual bool
563     isEligibleForTailCallOptimization(const CCState &CCInfo,
564                                       unsigned NextStackOffset,
565                                       const MipsFunctionInfo &FI) const = 0;
566 
567     /// copyByValArg - Copy argument registers which were used to pass a byval
568     /// argument to the stack. Create a stack frame object for the byval
569     /// argument.
570     void copyByValRegs(SDValue Chain, const SDLoc &DL,
571                        std::vector<SDValue> &OutChains, SelectionDAG &DAG,
572                        const ISD::ArgFlagsTy &Flags,
573                        SmallVectorImpl<SDValue> &InVals,
574                        const Argument *FuncArg, unsigned FirstReg,
575                        unsigned LastReg, const CCValAssign &VA,
576                        MipsCCState &State) const;
577 
578     /// passByValArg - Pass a byval argument in registers or on stack.
579     void passByValArg(SDValue Chain, const SDLoc &DL,
580                       std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
581                       SmallVectorImpl<SDValue> &MemOpChains, SDValue StackPtr,
582                       MachineFrameInfo &MFI, SelectionDAG &DAG, SDValue Arg,
583                       unsigned FirstReg, unsigned LastReg,
584                       const ISD::ArgFlagsTy &Flags, bool isLittle,
585                       const CCValAssign &VA) const;
586 
587     /// writeVarArgRegs - Write variable function arguments passed in registers
588     /// to the stack. Also create a stack frame object for the first variable
589     /// argument.
590     void writeVarArgRegs(std::vector<SDValue> &OutChains, SDValue Chain,
591                          const SDLoc &DL, SelectionDAG &DAG,
592                          CCState &State) const;
593 
594     SDValue
595     LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
596                          const SmallVectorImpl<ISD::InputArg> &Ins,
597                          const SDLoc &dl, SelectionDAG &DAG,
598                          SmallVectorImpl<SDValue> &InVals) const override;
599 
600     SDValue passArgOnStack(SDValue StackPtr, unsigned Offset, SDValue Chain,
601                            SDValue Arg, const SDLoc &DL, bool IsTailCall,
602                            SelectionDAG &DAG) const;
603 
604     SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
605                       SmallVectorImpl<SDValue> &InVals) const override;
606 
607     bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
608                         bool isVarArg,
609                         const SmallVectorImpl<ISD::OutputArg> &Outs,
610                         LLVMContext &Context) const override;
611 
612     SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
613                         const SmallVectorImpl<ISD::OutputArg> &Outs,
614                         const SmallVectorImpl<SDValue> &OutVals,
615                         const SDLoc &dl, SelectionDAG &DAG) const override;
616 
617     SDValue LowerInterruptReturn(SmallVectorImpl<SDValue> &RetOps,
618                                  const SDLoc &DL, SelectionDAG &DAG) const;
619 
620     bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const override;
621 
622     // Inline asm support
623     ConstraintType getConstraintType(StringRef Constraint) const override;
624 
625     /// Examine constraint string and operand type and determine a weight value.
626     /// The operand object must already have been set up with the operand type.
627     ConstraintWeight getSingleConstraintMatchWeight(
628       AsmOperandInfo &info, const char *constraint) const override;
629 
630     /// This function parses registers that appear in inline-asm constraints.
631     /// It returns pair (0, 0) on failure.
632     std::pair<unsigned, const TargetRegisterClass *>
633     parseRegForInlineAsmConstraint(StringRef C, MVT VT) const;
634 
635     std::pair<unsigned, const TargetRegisterClass *>
636     getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
637                                  StringRef Constraint, MVT VT) const override;
638 
639     /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
640     /// vector.  If it is invalid, don't add anything to Ops. If hasMemory is
641     /// true it means one of the asm constraint of the inline asm instruction
642     /// being processed is 'm'.
643     void LowerAsmOperandForConstraint(SDValue Op,
644                                       std::string &Constraint,
645                                       std::vector<SDValue> &Ops,
646                                       SelectionDAG &DAG) const override;
647 
648     unsigned
649     getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
650       if (ConstraintCode == "o")
651         return InlineAsm::Constraint_o;
652       if (ConstraintCode == "R")
653         return InlineAsm::Constraint_R;
654       if (ConstraintCode == "ZC")
655         return InlineAsm::Constraint_ZC;
656       return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
657     }
658 
659     bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
660                                Type *Ty, unsigned AS,
661                                Instruction *I = nullptr) const override;
662 
663     bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
664 
665     EVT getOptimalMemOpType(const MemOp &Op,
666                             const AttributeList &FuncAttributes) const override;
667 
668     /// isFPImmLegal - Returns true if the target can instruction select the
669     /// specified FP immediate natively. If false, the legalizer will
670     /// materialize the FP immediate as a load from a constant pool.
671     bool isFPImmLegal(const APFloat &Imm, EVT VT,
672                       bool ForCodeSize) const override;
673 
674     unsigned getJumpTableEncoding() const override;
675     bool useSoftFloat() const override;
676 
677     bool shouldInsertFencesForAtomic(const Instruction *I) const override {
678       return true;
679     }
680 
681     /// Emit a sign-extension using sll/sra, seb, or seh appropriately.
682     MachineBasicBlock *emitSignExtendToI32InReg(MachineInstr &MI,
683                                                 MachineBasicBlock *BB,
684                                                 unsigned Size, unsigned DstReg,
685                                                 unsigned SrcRec) const;
686 
687     MachineBasicBlock *emitAtomicBinary(MachineInstr &MI,
688                                         MachineBasicBlock *BB) const;
689     MachineBasicBlock *emitAtomicBinaryPartword(MachineInstr &MI,
690                                                 MachineBasicBlock *BB,
691                                                 unsigned Size) const;
692     MachineBasicBlock *emitAtomicCmpSwap(MachineInstr &MI,
693                                          MachineBasicBlock *BB) const;
694     MachineBasicBlock *emitAtomicCmpSwapPartword(MachineInstr &MI,
695                                                  MachineBasicBlock *BB,
696                                                  unsigned Size) const;
697     MachineBasicBlock *emitSEL_D(MachineInstr &MI, MachineBasicBlock *BB) const;
698     MachineBasicBlock *emitPseudoSELECT(MachineInstr &MI, MachineBasicBlock *BB,
699                                         bool isFPCmp, unsigned Opc) const;
700     MachineBasicBlock *emitPseudoD_SELECT(MachineInstr &MI,
701                                           MachineBasicBlock *BB) const;
702     MachineBasicBlock *emitLDR_W(MachineInstr &MI, MachineBasicBlock *BB) const;
703     MachineBasicBlock *emitLDR_D(MachineInstr &MI, MachineBasicBlock *BB) const;
704     MachineBasicBlock *emitSTR_W(MachineInstr &MI, MachineBasicBlock *BB) const;
705     MachineBasicBlock *emitSTR_D(MachineInstr &MI, MachineBasicBlock *BB) const;
706   };
707 
708   /// Create MipsTargetLowering objects.
709   const MipsTargetLowering *
710   createMips16TargetLowering(const MipsTargetMachine &TM,
711                              const MipsSubtarget &STI);
712   const MipsTargetLowering *
713   createMipsSETargetLowering(const MipsTargetMachine &TM,
714                              const MipsSubtarget &STI);
715 
716 namespace Mips {
717 
718 FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
719                          const TargetLibraryInfo *libInfo);
720 
721 } // end namespace Mips
722 
723 } // end namespace llvm
724 
725 #endif // LLVM_LIB_TARGET_MIPS_MIPSISELLOWERING_H
726