xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Mips/MipsISelLowering.h (revision 525fe93dc7487a1e63a90f6a2b956abc601963c1)
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 intrinsic 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(Type *Ty) const override;
287     bool isCheapToSpeculateCtlz(Type *Ty) const override;
288     bool hasBitTest(SDValue X, SDValue Y) const override;
289     bool shouldFoldConstantShiftPairToMask(const SDNode *N,
290                                            CombineLevel Level) const override;
291 
292     /// Return the register type for a given MVT, ensuring vectors are treated
293     /// as a series of gpr sized integers.
294     MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC,
295                                       EVT VT) const override;
296 
297     /// Return the number of registers for a given MVT, ensuring vectors are
298     /// treated as a series of gpr sized integers.
299     unsigned getNumRegistersForCallingConv(LLVMContext &Context,
300                                            CallingConv::ID CC,
301                                            EVT VT) const override;
302 
303     /// Break down vectors to the correct number of gpr sized integers.
304     unsigned getVectorTypeBreakdownForCallingConv(
305         LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT,
306         unsigned &NumIntermediates, MVT &RegisterVT) const override;
307 
308     /// Return the correct alignment for the current calling convention.
309     Align getABIAlignmentForCallingConv(Type *ArgTy,
310                                         const DataLayout &DL) const override {
311       const Align ABIAlign = DL.getABITypeAlign(ArgTy);
312       if (ArgTy->isVectorTy())
313         return std::min(ABIAlign, Align(8));
314       return ABIAlign;
315     }
316 
317     ISD::NodeType getExtendForAtomicOps() const override {
318       return ISD::SIGN_EXTEND;
319     }
320 
321     /// LowerOperation - Provide custom lowering hooks for some operations.
322     SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
323 
324     /// ReplaceNodeResults - Replace the results of node with an illegal result
325     /// type with new values built out of custom code.
326     ///
327     void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,
328                             SelectionDAG &DAG) const override;
329 
330     /// getTargetNodeName - This method returns the name of a target specific
331     //  DAG node.
332     const char *getTargetNodeName(unsigned Opcode) const override;
333 
334     /// getSetCCResultType - get the ISD::SETCC result ValueType
335     EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
336                            EVT VT) const override;
337 
338     SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
339 
340     MachineBasicBlock *
341     EmitInstrWithCustomInserter(MachineInstr &MI,
342                                 MachineBasicBlock *MBB) const override;
343 
344     void AdjustInstrPostInstrSelection(MachineInstr &MI,
345                                        SDNode *Node) const override;
346 
347     void HandleByVal(CCState *, unsigned &, Align) const override;
348 
349     Register getRegisterByName(const char* RegName, LLT VT,
350                                const MachineFunction &MF) const override;
351 
352     /// If a physical register, this returns the register that receives the
353     /// exception address on entry to an EH pad.
354     Register
355     getExceptionPointerRegister(const Constant *PersonalityFn) const override {
356       return ABI.IsN64() ? Mips::A0_64 : Mips::A0;
357     }
358 
359     /// If a physical register, this returns the register that receives the
360     /// exception typeid on entry to a landing pad.
361     Register
362     getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
363       return ABI.IsN64() ? Mips::A1_64 : Mips::A1;
364     }
365 
366     bool isJumpTableRelative() const override {
367       return getTargetMachine().isPositionIndependent();
368     }
369 
370    CCAssignFn *CCAssignFnForCall() const;
371 
372    CCAssignFn *CCAssignFnForReturn() const;
373 
374   protected:
375     SDValue getGlobalReg(SelectionDAG &DAG, EVT Ty) const;
376 
377     // This method creates the following nodes, which are necessary for
378     // computing a local symbol's address:
379     //
380     // (add (load (wrapper $gp, %got(sym)), %lo(sym))
381     template <class NodeTy>
382     SDValue getAddrLocal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG,
383                          bool IsN32OrN64) const {
384       unsigned GOTFlag = IsN32OrN64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT;
385       SDValue GOT = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty),
386                                 getTargetNode(N, Ty, DAG, GOTFlag));
387       SDValue Load =
388           DAG.getLoad(Ty, DL, DAG.getEntryNode(), GOT,
389                       MachinePointerInfo::getGOT(DAG.getMachineFunction()));
390       unsigned LoFlag = IsN32OrN64 ? MipsII::MO_GOT_OFST : MipsII::MO_ABS_LO;
391       SDValue Lo = DAG.getNode(MipsISD::Lo, DL, Ty,
392                                getTargetNode(N, Ty, DAG, LoFlag));
393       return DAG.getNode(ISD::ADD, DL, Ty, Load, Lo);
394     }
395 
396     // This method creates the following nodes, which are necessary for
397     // computing a global symbol's address:
398     //
399     // (load (wrapper $gp, %got(sym)))
400     template <class NodeTy>
401     SDValue getAddrGlobal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG,
402                           unsigned Flag, SDValue Chain,
403                           const MachinePointerInfo &PtrInfo) const {
404       SDValue Tgt = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty),
405                                 getTargetNode(N, Ty, DAG, Flag));
406       return DAG.getLoad(Ty, DL, Chain, Tgt, PtrInfo);
407     }
408 
409     // This method creates the following nodes, which are necessary for
410     // computing a global symbol's address in large-GOT mode:
411     //
412     // (load (wrapper (add %hi(sym), $gp), %lo(sym)))
413     template <class NodeTy>
414     SDValue getAddrGlobalLargeGOT(NodeTy *N, const SDLoc &DL, EVT Ty,
415                                   SelectionDAG &DAG, unsigned HiFlag,
416                                   unsigned LoFlag, SDValue Chain,
417                                   const MachinePointerInfo &PtrInfo) const {
418       SDValue Hi = DAG.getNode(MipsISD::GotHi, DL, Ty,
419                                getTargetNode(N, Ty, DAG, HiFlag));
420       Hi = DAG.getNode(ISD::ADD, DL, Ty, Hi, getGlobalReg(DAG, Ty));
421       SDValue Wrapper = DAG.getNode(MipsISD::Wrapper, DL, Ty, Hi,
422                                     getTargetNode(N, Ty, DAG, LoFlag));
423       return DAG.getLoad(Ty, DL, Chain, Wrapper, PtrInfo);
424     }
425 
426     // This method creates the following nodes, which are necessary for
427     // computing a symbol's address in non-PIC mode:
428     //
429     // (add %hi(sym), %lo(sym))
430     //
431     // This method covers O32, N32 and N64 in sym32 mode.
432     template <class NodeTy>
433     SDValue getAddrNonPIC(NodeTy *N, const SDLoc &DL, EVT Ty,
434                           SelectionDAG &DAG) const {
435       SDValue Hi = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI);
436       SDValue Lo = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO);
437       return DAG.getNode(ISD::ADD, DL, Ty,
438                          DAG.getNode(MipsISD::Hi, DL, Ty, Hi),
439                          DAG.getNode(MipsISD::Lo, DL, Ty, Lo));
440    }
441 
442    // This method creates the following nodes, which are necessary for
443    // computing a symbol's address in non-PIC mode for N64.
444    //
445    // (add (shl (add (shl (add %highest(sym), %higher(sim)), 16), %high(sym)),
446    //            16), %lo(%sym))
447    //
448    // FIXME: This method is not efficent for (micro)MIPS64R6.
449    template <class NodeTy>
450    SDValue getAddrNonPICSym64(NodeTy *N, const SDLoc &DL, EVT Ty,
451                           SelectionDAG &DAG) const {
452       SDValue Hi = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI);
453       SDValue Lo = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO);
454 
455       SDValue Highest =
456           DAG.getNode(MipsISD::Highest, DL, Ty,
457                       getTargetNode(N, Ty, DAG, MipsII::MO_HIGHEST));
458       SDValue Higher = getTargetNode(N, Ty, DAG, MipsII::MO_HIGHER);
459       SDValue HigherPart =
460           DAG.getNode(ISD::ADD, DL, Ty, Highest,
461                       DAG.getNode(MipsISD::Higher, DL, Ty, Higher));
462       SDValue Cst = DAG.getConstant(16, DL, MVT::i32);
463       SDValue Shift = DAG.getNode(ISD::SHL, DL, Ty, HigherPart, Cst);
464       SDValue Add = DAG.getNode(ISD::ADD, DL, Ty, Shift,
465                                 DAG.getNode(MipsISD::Hi, DL, Ty, Hi));
466       SDValue Shift2 = DAG.getNode(ISD::SHL, DL, Ty, Add, Cst);
467 
468       return DAG.getNode(ISD::ADD, DL, Ty, Shift2,
469                          DAG.getNode(MipsISD::Lo, DL, Ty, Lo));
470    }
471 
472     // This method creates the following nodes, which are necessary for
473     // computing a symbol's address using gp-relative addressing:
474     //
475     // (add $gp, %gp_rel(sym))
476     template <class NodeTy>
477     SDValue getAddrGPRel(NodeTy *N, const SDLoc &DL, EVT Ty,
478                          SelectionDAG &DAG, bool IsN64) const {
479       SDValue GPRel = getTargetNode(N, Ty, DAG, MipsII::MO_GPREL);
480       return DAG.getNode(
481           ISD::ADD, DL, Ty,
482           DAG.getRegister(IsN64 ? Mips::GP_64 : Mips::GP, Ty),
483           DAG.getNode(MipsISD::GPRel, DL, DAG.getVTList(Ty), GPRel));
484     }
485 
486     /// This function fills Ops, which is the list of operands that will later
487     /// be used when a function call node is created. It also generates
488     /// copyToReg nodes to set up argument registers.
489     virtual void
490     getOpndList(SmallVectorImpl<SDValue> &Ops,
491                 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
492                 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
493                 bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
494                 SDValue Chain) const;
495 
496   protected:
497     SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const;
498     SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const;
499 
500     // Subtarget Info
501     const MipsSubtarget &Subtarget;
502     // Cache the ABI from the TargetMachine, we use it everywhere.
503     const MipsABIInfo &ABI;
504 
505   private:
506     // Create a TargetGlobalAddress node.
507     SDValue getTargetNode(GlobalAddressSDNode *N, EVT Ty, SelectionDAG &DAG,
508                           unsigned Flag) const;
509 
510     // Create a TargetExternalSymbol node.
511     SDValue getTargetNode(ExternalSymbolSDNode *N, EVT Ty, SelectionDAG &DAG,
512                           unsigned Flag) const;
513 
514     // Create a TargetBlockAddress node.
515     SDValue getTargetNode(BlockAddressSDNode *N, EVT Ty, SelectionDAG &DAG,
516                           unsigned Flag) const;
517 
518     // Create a TargetJumpTable node.
519     SDValue getTargetNode(JumpTableSDNode *N, EVT Ty, SelectionDAG &DAG,
520                           unsigned Flag) const;
521 
522     // Create a TargetConstantPool node.
523     SDValue getTargetNode(ConstantPoolSDNode *N, EVT Ty, SelectionDAG &DAG,
524                           unsigned Flag) const;
525 
526     // Lower Operand helpers
527     SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
528                             CallingConv::ID CallConv, bool isVarArg,
529                             const SmallVectorImpl<ISD::InputArg> &Ins,
530                             const SDLoc &dl, SelectionDAG &DAG,
531                             SmallVectorImpl<SDValue> &InVals,
532                             TargetLowering::CallLoweringInfo &CLI) const;
533 
534     // Lower Operand specifics
535     SDValue lowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
536     SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
537     SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
538     SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
539     SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
540     SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
541     SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const;
542     SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const;
543     SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
544     SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const;
545     SDValue lowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const;
546     SDValue lowerFABS(SDValue Op, SelectionDAG &DAG) const;
547     SDValue lowerFABS32(SDValue Op, SelectionDAG &DAG,
548                         bool HasExtractInsert) const;
549     SDValue lowerFABS64(SDValue Op, SelectionDAG &DAG,
550                         bool HasExtractInsert) const;
551     SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
552     SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
553     SDValue lowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
554     SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
555     SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG& DAG) const;
556     SDValue lowerShiftRightParts(SDValue Op, SelectionDAG& DAG,
557                                  bool IsSRA) const;
558     SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const;
559     SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const;
560 
561     /// isEligibleForTailCallOptimization - Check whether the call is eligible
562     /// for tail call optimization.
563     virtual bool
564     isEligibleForTailCallOptimization(const CCState &CCInfo,
565                                       unsigned NextStackOffset,
566                                       const MipsFunctionInfo &FI) const = 0;
567 
568     /// copyByValArg - Copy argument registers which were used to pass a byval
569     /// argument to the stack. Create a stack frame object for the byval
570     /// argument.
571     void copyByValRegs(SDValue Chain, const SDLoc &DL,
572                        std::vector<SDValue> &OutChains, SelectionDAG &DAG,
573                        const ISD::ArgFlagsTy &Flags,
574                        SmallVectorImpl<SDValue> &InVals,
575                        const Argument *FuncArg, unsigned FirstReg,
576                        unsigned LastReg, const CCValAssign &VA,
577                        MipsCCState &State) const;
578 
579     /// passByValArg - Pass a byval argument in registers or on stack.
580     void passByValArg(SDValue Chain, const SDLoc &DL,
581                       std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
582                       SmallVectorImpl<SDValue> &MemOpChains, SDValue StackPtr,
583                       MachineFrameInfo &MFI, SelectionDAG &DAG, SDValue Arg,
584                       unsigned FirstReg, unsigned LastReg,
585                       const ISD::ArgFlagsTy &Flags, bool isLittle,
586                       const CCValAssign &VA) const;
587 
588     /// writeVarArgRegs - Write variable function arguments passed in registers
589     /// to the stack. Also create a stack frame object for the first variable
590     /// argument.
591     void writeVarArgRegs(std::vector<SDValue> &OutChains, SDValue Chain,
592                          const SDLoc &DL, SelectionDAG &DAG,
593                          CCState &State) const;
594 
595     SDValue
596     LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
597                          const SmallVectorImpl<ISD::InputArg> &Ins,
598                          const SDLoc &dl, SelectionDAG &DAG,
599                          SmallVectorImpl<SDValue> &InVals) const override;
600 
601     SDValue passArgOnStack(SDValue StackPtr, unsigned Offset, SDValue Chain,
602                            SDValue Arg, const SDLoc &DL, bool IsTailCall,
603                            SelectionDAG &DAG) const;
604 
605     SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
606                       SmallVectorImpl<SDValue> &InVals) const override;
607 
608     bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
609                         bool isVarArg,
610                         const SmallVectorImpl<ISD::OutputArg> &Outs,
611                         LLVMContext &Context) const override;
612 
613     SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
614                         const SmallVectorImpl<ISD::OutputArg> &Outs,
615                         const SmallVectorImpl<SDValue> &OutVals,
616                         const SDLoc &dl, SelectionDAG &DAG) const override;
617 
618     SDValue LowerInterruptReturn(SmallVectorImpl<SDValue> &RetOps,
619                                  const SDLoc &DL, SelectionDAG &DAG) const;
620 
621     bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const override;
622 
623     // Inline asm support
624     ConstraintType getConstraintType(StringRef Constraint) const override;
625 
626     /// Examine constraint string and operand type and determine a weight value.
627     /// The operand object must already have been set up with the operand type.
628     ConstraintWeight getSingleConstraintMatchWeight(
629       AsmOperandInfo &info, const char *constraint) const override;
630 
631     /// This function parses registers that appear in inline-asm constraints.
632     /// It returns pair (0, 0) on failure.
633     std::pair<unsigned, const TargetRegisterClass *>
634     parseRegForInlineAsmConstraint(StringRef C, MVT VT) const;
635 
636     std::pair<unsigned, const TargetRegisterClass *>
637     getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
638                                  StringRef Constraint, MVT VT) const override;
639 
640     /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
641     /// vector.  If it is invalid, don't add anything to Ops. If hasMemory is
642     /// true it means one of the asm constraint of the inline asm instruction
643     /// being processed is 'm'.
644     void LowerAsmOperandForConstraint(SDValue Op,
645                                       std::string &Constraint,
646                                       std::vector<SDValue> &Ops,
647                                       SelectionDAG &DAG) const override;
648 
649     unsigned
650     getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
651       if (ConstraintCode == "o")
652         return InlineAsm::Constraint_o;
653       if (ConstraintCode == "R")
654         return InlineAsm::Constraint_R;
655       if (ConstraintCode == "ZC")
656         return InlineAsm::Constraint_ZC;
657       return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
658     }
659 
660     bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
661                                Type *Ty, unsigned AS,
662                                Instruction *I = nullptr) const override;
663 
664     bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
665 
666     EVT getOptimalMemOpType(const MemOp &Op,
667                             const AttributeList &FuncAttributes) const override;
668 
669     /// isFPImmLegal - Returns true if the target can instruction select the
670     /// specified FP immediate natively. If false, the legalizer will
671     /// materialize the FP immediate as a load from a constant pool.
672     bool isFPImmLegal(const APFloat &Imm, EVT VT,
673                       bool ForCodeSize) const override;
674 
675     unsigned getJumpTableEncoding() const override;
676     bool useSoftFloat() const override;
677 
678     bool shouldInsertFencesForAtomic(const Instruction *I) const override {
679       return true;
680     }
681 
682     /// Emit a sign-extension using sll/sra, seb, or seh appropriately.
683     MachineBasicBlock *emitSignExtendToI32InReg(MachineInstr &MI,
684                                                 MachineBasicBlock *BB,
685                                                 unsigned Size, unsigned DstReg,
686                                                 unsigned SrcRec) const;
687 
688     MachineBasicBlock *emitAtomicBinary(MachineInstr &MI,
689                                         MachineBasicBlock *BB) const;
690     MachineBasicBlock *emitAtomicBinaryPartword(MachineInstr &MI,
691                                                 MachineBasicBlock *BB,
692                                                 unsigned Size) const;
693     MachineBasicBlock *emitAtomicCmpSwap(MachineInstr &MI,
694                                          MachineBasicBlock *BB) const;
695     MachineBasicBlock *emitAtomicCmpSwapPartword(MachineInstr &MI,
696                                                  MachineBasicBlock *BB,
697                                                  unsigned Size) const;
698     MachineBasicBlock *emitSEL_D(MachineInstr &MI, MachineBasicBlock *BB) const;
699     MachineBasicBlock *emitPseudoSELECT(MachineInstr &MI, MachineBasicBlock *BB,
700                                         bool isFPCmp, unsigned Opc) const;
701     MachineBasicBlock *emitPseudoD_SELECT(MachineInstr &MI,
702                                           MachineBasicBlock *BB) const;
703     MachineBasicBlock *emitLDR_W(MachineInstr &MI, MachineBasicBlock *BB) const;
704     MachineBasicBlock *emitLDR_D(MachineInstr &MI, MachineBasicBlock *BB) const;
705     MachineBasicBlock *emitSTR_W(MachineInstr &MI, MachineBasicBlock *BB) const;
706     MachineBasicBlock *emitSTR_D(MachineInstr &MI, MachineBasicBlock *BB) const;
707   };
708 
709   /// Create MipsTargetLowering objects.
710   const MipsTargetLowering *
711   createMips16TargetLowering(const MipsTargetMachine &TM,
712                              const MipsSubtarget &STI);
713   const MipsTargetLowering *
714   createMipsSETargetLowering(const MipsTargetMachine &TM,
715                              const MipsSubtarget &STI);
716 
717 namespace Mips {
718 
719 FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
720                          const TargetLibraryInfo *libInfo);
721 
722 } // end namespace Mips
723 
724 } // end namespace llvm
725 
726 #endif // LLVM_LIB_TARGET_MIPS_MIPSISELLOWERING_H
727