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