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