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