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