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