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