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