brintos

brintos / llvm-project-archived public Read only

0
0
Text · 28.6 KiB · 7c489b3 Raw
767 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines the interfaces that Mips uses to lower LLVM code into a10// selection DAG.11//12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_LIB_TARGET_MIPS_MIPSISELLOWERING_H15#define LLVM_LIB_TARGET_MIPS_MIPSISELLOWERING_H16 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 38namespace llvm {39 40class Argument;41class FastISel;42class FunctionLoweringInfo;43class MachineBasicBlock;44class MachineFrameInfo;45class MachineInstr;46class MipsCCState;47class MipsFunctionInfo;48class MipsSubtarget;49class MipsTargetMachine;50class TargetLibraryInfo;51class 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 call63      TailCall,64 65      // Get the Highest (63-48) 16 bits from a 64-bit immediate66      Highest,67 68      // Get the Higher (47-32) 16 bits from a 64-bit immediate69      Higher,70 71      // Get the High 16 bits from a 32/64-bit immediate72      // No relation with Mips Hi register73      Hi,74 75      // Get the Lower 16 bits from a 32/64-bit immediate76      // No relation with Mips Lo register77      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 Pointer89      ThreadPointer,90 91      // Vector Floating Point Multiply and Subtract92      FMS,93 94      // Floating Point Branch Conditional95      FPBrcond,96 97      // Floating Point Compare98      FPCmp,99 100      // Floating point Abs101      FAbs,102 103      // Floating point select104      FSELECT,105 106      // Node used to generate an MTC1 i32 to f64 instruction107      MTC1_D64,108 109      // Floating Point Conditional Moves110      CMovFP_T,111      CMovFP_F,112 113      // FP-to-int truncation node.114      TruncIntFP,115 116      // Return117      Ret,118 119      // Interrupt, exception, error trap Return120      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 nodes137      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 operand226      VSHF,  // Generic shuffle227      SHF,   // 4-element set shuffle.228      ILVEV, // Interleave even elements229      ILVOD, // Interleave odd elements230      ILVL,  // Interleave left elements231      ILVR,  // Interleave right elements232      PCKEV, // Pack even elements233      PCKOD, // Pack odd elements234 235      // Vector Lane Copy236      INSVE, // Copy element from one vector to another237 238      // Combined (XOR (OR $a, $b), -1)239      VNOR,240 241      // Extended vector element extraction242      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 MipsISD263 264  //===--------------------------------------------------------------------===//265  // TargetLowering Implementation266  //===--------------------------------------------------------------------===//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) const override;294 295    /// Return the register type for a given MVT, ensuring vectors are treated296    /// as a series of gpr sized integers.297    MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC,298                                      EVT VT) const override;299 300    /// Return the number of registers for a given MVT, ensuring vectors are301    /// treated as a series of gpr sized integers.302    unsigned getNumRegistersForCallingConv(LLVMContext &Context,303                                           CallingConv::ID CC,304                                           EVT VT) const override;305 306    /// Break down vectors to the correct number of gpr sized integers.307    unsigned getVectorTypeBreakdownForCallingConv(308        LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT,309        unsigned &NumIntermediates, MVT &RegisterVT) const override;310 311    /// Return the correct alignment for the current calling convention.312    Align getABIAlignmentForCallingConv(Type *ArgTy,313                                        const DataLayout &DL) const override {314      const Align ABIAlign = DL.getABITypeAlign(ArgTy);315      if (ArgTy->isVectorTy())316        return std::min(ABIAlign, Align(8));317      return ABIAlign;318    }319 320    ISD::NodeType getExtendForAtomicOps() const override {321      return ISD::SIGN_EXTEND;322    }323 324    /// LowerOperation - Provide custom lowering hooks for some operations.325    SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;326 327    /// ReplaceNodeResults - Replace the results of node with an illegal result328    /// type with new values built out of custom code.329    ///330    void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,331                            SelectionDAG &DAG) const override;332 333    /// getTargetNodeName - This method returns the name of a target specific334    //  DAG node.335    const char *getTargetNodeName(unsigned Opcode) const override;336 337    /// getSetCCResultType - get the ISD::SETCC result ValueType338    EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,339                           EVT VT) const override;340 341    SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;342 343    MachineBasicBlock *344    EmitInstrWithCustomInserter(MachineInstr &MI,345                                MachineBasicBlock *MBB) const override;346 347    void AdjustInstrPostInstrSelection(MachineInstr &MI,348                                       SDNode *Node) const override;349 350    void HandleByVal(CCState *, unsigned &, Align) const override;351 352    Register getRegisterByName(const char* RegName, LLT VT,353                               const MachineFunction &MF) const override;354 355    /// If a physical register, this returns the register that receives the356    /// exception address on entry to an EH pad.357    Register358    getExceptionPointerRegister(const Constant *PersonalityFn) const override {359      return ABI.IsN64() ? Mips::A0_64 : Mips::A0;360    }361 362    /// If a physical register, this returns the register that receives the363    /// exception typeid on entry to a landing pad.364    Register365    getExceptionSelectorRegister(const Constant *PersonalityFn) const override {366      return ABI.IsN64() ? Mips::A1_64 : Mips::A1;367    }368 369    bool softPromoteHalfType() const override { return true; }370 371    bool isJumpTableRelative() const override {372      return getTargetMachine().isPositionIndependent();373    }374 375   CCAssignFn *CCAssignFnForCall() const;376 377   CCAssignFn *CCAssignFnForReturn() const;378 379  protected:380    SDValue getGlobalReg(SelectionDAG &DAG, EVT Ty) const;381 382    // This method creates the following nodes, which are necessary for383    // computing a local symbol's address:384    //385    // (add (load (wrapper $gp, %got(sym)), %lo(sym))386    template <class NodeTy>387    SDValue getAddrLocal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG,388                         bool IsN32OrN64) const {389      unsigned GOTFlag = IsN32OrN64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT;390      SDValue GOT = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty),391                                getTargetNode(N, Ty, DAG, GOTFlag));392      SDValue Load =393          DAG.getLoad(Ty, DL, DAG.getEntryNode(), GOT,394                      MachinePointerInfo::getGOT(DAG.getMachineFunction()));395      unsigned LoFlag = IsN32OrN64 ? MipsII::MO_GOT_OFST : MipsII::MO_ABS_LO;396      SDValue Lo = DAG.getNode(MipsISD::Lo, DL, Ty,397                               getTargetNode(N, Ty, DAG, LoFlag));398      return DAG.getNode(ISD::ADD, DL, Ty, Load, Lo);399    }400 401    // This method creates the following nodes, which are necessary for402    // computing a global symbol's address:403    //404    // (load (wrapper $gp, %got(sym)))405    template <class NodeTy>406    SDValue getAddrGlobal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG,407                          unsigned Flag, SDValue Chain,408                          const MachinePointerInfo &PtrInfo) const {409      SDValue Tgt = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty),410                                getTargetNode(N, Ty, DAG, Flag));411      return DAG.getLoad(Ty, DL, Chain, Tgt, PtrInfo);412    }413 414    // This method creates the following nodes, which are necessary for415    // computing a global symbol's address in large-GOT mode:416    //417    // (load (wrapper (add %hi(sym), $gp), %lo(sym)))418    template <class NodeTy>419    SDValue getAddrGlobalLargeGOT(NodeTy *N, const SDLoc &DL, EVT Ty,420                                  SelectionDAG &DAG, unsigned HiFlag,421                                  unsigned LoFlag, SDValue Chain,422                                  const MachinePointerInfo &PtrInfo) const {423      SDValue Hi = DAG.getNode(MipsISD::GotHi, DL, Ty,424                               getTargetNode(N, Ty, DAG, HiFlag));425      Hi = DAG.getNode(ISD::ADD, DL, Ty, Hi, getGlobalReg(DAG, Ty));426      SDValue Wrapper = DAG.getNode(MipsISD::Wrapper, DL, Ty, Hi,427                                    getTargetNode(N, Ty, DAG, LoFlag));428      return DAG.getLoad(Ty, DL, Chain, Wrapper, PtrInfo);429    }430 431    // This method creates the following nodes, which are necessary for432    // computing a symbol's address in non-PIC mode:433    //434    // (add %hi(sym), %lo(sym))435    //436    // This method covers O32, N32 and N64 in sym32 mode.437    template <class NodeTy>438    SDValue getAddrNonPIC(NodeTy *N, const SDLoc &DL, EVT Ty,439                          SelectionDAG &DAG) const {440      SDValue Hi = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI);441      SDValue Lo = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO);442      return DAG.getNode(ISD::ADD, DL, Ty,443                         DAG.getNode(MipsISD::Hi, DL, Ty, Hi),444                         DAG.getNode(MipsISD::Lo, DL, Ty, Lo));445   }446 447   // This method creates the following nodes, which are necessary for448   // computing a symbol's address in non-PIC mode for N64.449   //450   // (add (shl (add (shl (add %highest(sym), %higher(sim)), 16), %high(sym)),451   //            16), %lo(%sym))452   //453   // FIXME: This method is not efficent for (micro)MIPS64R6.454   template <class NodeTy>455   SDValue getAddrNonPICSym64(NodeTy *N, const SDLoc &DL, EVT Ty,456                          SelectionDAG &DAG) const {457      SDValue Hi = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI);458      SDValue Lo = getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO);459 460      SDValue Highest =461          DAG.getNode(MipsISD::Highest, DL, Ty,462                      getTargetNode(N, Ty, DAG, MipsII::MO_HIGHEST));463      SDValue Higher = getTargetNode(N, Ty, DAG, MipsII::MO_HIGHER);464      SDValue HigherPart =465          DAG.getNode(ISD::ADD, DL, Ty, Highest,466                      DAG.getNode(MipsISD::Higher, DL, Ty, Higher));467      SDValue Cst = DAG.getConstant(16, DL, MVT::i32);468      SDValue Shift = DAG.getNode(ISD::SHL, DL, Ty, HigherPart, Cst);469      SDValue Add = DAG.getNode(ISD::ADD, DL, Ty, Shift,470                                DAG.getNode(MipsISD::Hi, DL, Ty, Hi));471      SDValue Shift2 = DAG.getNode(ISD::SHL, DL, Ty, Add, Cst);472 473      return DAG.getNode(ISD::ADD, DL, Ty, Shift2,474                         DAG.getNode(MipsISD::Lo, DL, Ty, Lo));475   }476 477    // This method creates the following nodes, which are necessary for478    // computing a symbol's address using gp-relative addressing:479    //480    // (add $gp, %gp_rel(sym))481    template <class NodeTy>482    SDValue getAddrGPRel(NodeTy *N, const SDLoc &DL, EVT Ty,483                         SelectionDAG &DAG, bool IsN64) const {484      SDValue GPRel = getTargetNode(N, Ty, DAG, MipsII::MO_GPREL);485      return DAG.getNode(486          ISD::ADD, DL, Ty,487          DAG.getRegister(IsN64 ? Mips::GP_64 : Mips::GP, Ty),488          DAG.getNode(MipsISD::GPRel, DL, DAG.getVTList(Ty), GPRel));489    }490 491    // This method creates the following nodes, which are necessary for492    // loading a dllimported symbol:493    //494    // (lw (add (shl(%high(sym), 16), %low(sym)))495    template <class NodeTy>496    SDValue getDllimportSymbol(NodeTy *N, const SDLoc &DL, EVT Ty,497                               SelectionDAG &DAG) const {498      SDValue Hi =499          getTargetNode(N, Ty, DAG, MipsII::MO_ABS_HI | MipsII::MO_DLLIMPORT);500      SDValue Lo =501          getTargetNode(N, Ty, DAG, MipsII::MO_ABS_LO | MipsII::MO_DLLIMPORT);502      return DAG.getNode(ISD::ADD, DL, Ty, DAG.getNode(MipsISD::Lo, DL, Ty, Lo),503                         DAG.getNode(MipsISD::Hi, DL, Ty, Hi));504    }505 506    // This method creates the following nodes, which are necessary for507    // loading a dllimported global variable:508    //509    // (lw (lw (add (shl(%high(sym), 16), %low(sym))))510    template <class NodeTy>511    SDValue getDllimportVariable(NodeTy *N, const SDLoc &DL, EVT Ty,512                                 SelectionDAG &DAG, SDValue Chain,513                                 const MachinePointerInfo &PtrInfo) const {514      return DAG.getLoad(Ty, DL, Chain, getDllimportSymbol(N, DL, Ty, DAG),515                         PtrInfo);516    }517 518    /// This function fills Ops, which is the list of operands that will later519    /// be used when a function call node is created. It also generates520    /// copyToReg nodes to set up argument registers.521    virtual void522    getOpndList(SmallVectorImpl<SDValue> &Ops,523                std::deque<std::pair<unsigned, SDValue>> &RegsToPass,524                bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,525                bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,526                SDValue Chain) const;527 528  protected:529    SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const;530    SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const;531 532    // Subtarget Info533    const MipsSubtarget &Subtarget;534    // Cache the ABI from the TargetMachine, we use it everywhere.535    const MipsABIInfo &ABI;536 537  private:538    // Create a TargetGlobalAddress node.539    SDValue getTargetNode(GlobalAddressSDNode *N, EVT Ty, SelectionDAG &DAG,540                          unsigned Flag) const;541 542    // Create a TargetExternalSymbol node.543    SDValue getTargetNode(ExternalSymbolSDNode *N, EVT Ty, SelectionDAG &DAG,544                          unsigned Flag) const;545 546    // Create a TargetBlockAddress node.547    SDValue getTargetNode(BlockAddressSDNode *N, EVT Ty, SelectionDAG &DAG,548                          unsigned Flag) const;549 550    // Create a TargetJumpTable node.551    SDValue getTargetNode(JumpTableSDNode *N, EVT Ty, SelectionDAG &DAG,552                          unsigned Flag) const;553 554    // Create a TargetConstantPool node.555    SDValue getTargetNode(ConstantPoolSDNode *N, EVT Ty, SelectionDAG &DAG,556                          unsigned Flag) const;557 558    // Lower Operand helpers559    SDValue LowerCallResult(SDValue Chain, SDValue InGlue,560                            CallingConv::ID CallConv, bool isVarArg,561                            const SmallVectorImpl<ISD::InputArg> &Ins,562                            const SDLoc &dl, SelectionDAG &DAG,563                            SmallVectorImpl<SDValue> &InVals,564                            TargetLowering::CallLoweringInfo &CLI) const;565 566    // Lower Operand specifics567    SDValue lowerBRCOND(SDValue Op, SelectionDAG &DAG) const;568    SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;569    SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;570    SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;571    SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;572    SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;573    SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const;574    SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const;575    SDValue lowerFSETCC(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    SDValue lowerSTRICT_FP_TO_INT(SDValue Op, SelectionDAG &DAG) const;595    SDValue lowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const;596 597    /// isEligibleForTailCallOptimization - Check whether the call is eligible598    /// for tail call optimization.599    virtual bool600    isEligibleForTailCallOptimization(const CCState &CCInfo,601                                      unsigned NextStackOffset,602                                      const MipsFunctionInfo &FI) const = 0;603 604    /// copyByValArg - Copy argument registers which were used to pass a byval605    /// argument to the stack. Create a stack frame object for the byval606    /// argument.607    void copyByValRegs(SDValue Chain, const SDLoc &DL,608                       std::vector<SDValue> &OutChains, SelectionDAG &DAG,609                       const ISD::ArgFlagsTy &Flags,610                       SmallVectorImpl<SDValue> &InVals,611                       const Argument *FuncArg, unsigned FirstReg,612                       unsigned LastReg, const CCValAssign &VA,613                       MipsCCState &State) const;614 615    /// passByValArg - Pass a byval argument in registers or on stack.616    void passByValArg(SDValue Chain, const SDLoc &DL,617                      std::deque<std::pair<unsigned, SDValue>> &RegsToPass,618                      SmallVectorImpl<SDValue> &MemOpChains, SDValue StackPtr,619                      MachineFrameInfo &MFI, SelectionDAG &DAG, SDValue Arg,620                      unsigned FirstReg, unsigned LastReg,621                      const ISD::ArgFlagsTy &Flags, bool isLittle,622                      const CCValAssign &VA) const;623 624    /// writeVarArgRegs - Write variable function arguments passed in registers625    /// to the stack. Also create a stack frame object for the first variable626    /// argument.627    void writeVarArgRegs(std::vector<SDValue> &OutChains, SDValue Chain,628                         const SDLoc &DL, SelectionDAG &DAG,629                         CCState &State) const;630 631    SDValue632    LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,633                         const SmallVectorImpl<ISD::InputArg> &Ins,634                         const SDLoc &dl, SelectionDAG &DAG,635                         SmallVectorImpl<SDValue> &InVals) const override;636 637    SDValue passArgOnStack(SDValue StackPtr, unsigned Offset, SDValue Chain,638                           SDValue Arg, const SDLoc &DL, bool IsTailCall,639                           SelectionDAG &DAG) const;640 641    SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,642                      SmallVectorImpl<SDValue> &InVals) const override;643 644    bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,645                        bool isVarArg,646                        const SmallVectorImpl<ISD::OutputArg> &Outs,647                        LLVMContext &Context, const Type *RetTy) const override;648 649    SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,650                        const SmallVectorImpl<ISD::OutputArg> &Outs,651                        const SmallVectorImpl<SDValue> &OutVals,652                        const SDLoc &dl, SelectionDAG &DAG) const override;653 654    SDValue LowerInterruptReturn(SmallVectorImpl<SDValue> &RetOps,655                                 const SDLoc &DL, SelectionDAG &DAG) const;656 657    bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const override;658 659    // Inline asm support660    ConstraintType getConstraintType(StringRef Constraint) const override;661 662    /// Examine constraint string and operand type and determine a weight value.663    /// The operand object must already have been set up with the operand type.664    ConstraintWeight getSingleConstraintMatchWeight(665      AsmOperandInfo &info, const char *constraint) const override;666 667    /// This function parses registers that appear in inline-asm constraints.668    /// It returns pair (0, 0) on failure.669    std::pair<unsigned, const TargetRegisterClass *>670    parseRegForInlineAsmConstraint(StringRef C, MVT VT) const;671 672    std::pair<unsigned, const TargetRegisterClass *>673    getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,674                                 StringRef Constraint, MVT VT) const override;675 676    /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops677    /// vector.  If it is invalid, don't add anything to Ops. If hasMemory is678    /// true it means one of the asm constraint of the inline asm instruction679    /// being processed is 'm'.680    void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint,681                                      std::vector<SDValue> &Ops,682                                      SelectionDAG &DAG) const override;683 684    InlineAsm::ConstraintCode685    getInlineAsmMemConstraint(StringRef ConstraintCode) const override {686      if (ConstraintCode == "o")687        return InlineAsm::ConstraintCode::o;688      if (ConstraintCode == "R")689        return InlineAsm::ConstraintCode::R;690      if (ConstraintCode == "ZC")691        return InlineAsm::ConstraintCode::ZC;692      return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);693    }694 695    bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,696                               Type *Ty, unsigned AS,697                               Instruction *I = nullptr) const override;698 699    bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;700 701    EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,702                            const AttributeList &FuncAttributes) const override;703 704    /// isFPImmLegal - Returns true if the target can instruction select the705    /// specified FP immediate natively. If false, the legalizer will706    /// materialize the FP immediate as a load from a constant pool.707    bool isFPImmLegal(const APFloat &Imm, EVT VT,708                      bool ForCodeSize) const override;709 710    bool isLegalICmpImmediate(int64_t Imm) const override;711    bool isLegalAddImmediate(int64_t Imm) const override;712 713    unsigned getJumpTableEncoding() const override;714    SDValue getPICJumpTableRelocBase(SDValue Table,715                                     SelectionDAG &DAG) const override;716    bool useSoftFloat() const override;717 718    bool shouldInsertFencesForAtomic(const Instruction *I) const override {719      return true;720    }721 722    /// Emit a sign-extension using sll/sra, seb, or seh appropriately.723    MachineBasicBlock *emitSignExtendToI32InReg(MachineInstr &MI,724                                                MachineBasicBlock *BB,725                                                unsigned Size, unsigned DstReg,726                                                unsigned SrcRec) const;727 728    MachineBasicBlock *emitAtomicBinary(MachineInstr &MI,729                                        MachineBasicBlock *BB) const;730    MachineBasicBlock *emitAtomicBinaryPartword(MachineInstr &MI,731                                                MachineBasicBlock *BB,732                                                unsigned Size) const;733    MachineBasicBlock *emitAtomicCmpSwap(MachineInstr &MI,734                                         MachineBasicBlock *BB) const;735    MachineBasicBlock *emitAtomicCmpSwapPartword(MachineInstr &MI,736                                                 MachineBasicBlock *BB,737                                                 unsigned Size) const;738    MachineBasicBlock *emitSEL_D(MachineInstr &MI, MachineBasicBlock *BB) const;739    MachineBasicBlock *emitPseudoSELECT(MachineInstr &MI, MachineBasicBlock *BB,740                                        bool isFPCmp, unsigned Opc) const;741    MachineBasicBlock *emitPseudoD_SELECT(MachineInstr &MI,742                                          MachineBasicBlock *BB) const;743    MachineBasicBlock *emitLDR_W(MachineInstr &MI, MachineBasicBlock *BB) const;744    MachineBasicBlock *emitLDR_D(MachineInstr &MI, MachineBasicBlock *BB) const;745    MachineBasicBlock *emitSTR_W(MachineInstr &MI, MachineBasicBlock *BB) const;746    MachineBasicBlock *emitSTR_D(MachineInstr &MI, MachineBasicBlock *BB) const;747  };748 749  /// Create MipsTargetLowering objects.750  const MipsTargetLowering *751  createMips16TargetLowering(const MipsTargetMachine &TM,752                             const MipsSubtarget &STI);753  const MipsTargetLowering *754  createMipsSETargetLowering(const MipsTargetMachine &TM,755                             const MipsSubtarget &STI);756 757namespace Mips {758 759FastISel *createFastISel(FunctionLoweringInfo &funcInfo,760                         const TargetLibraryInfo *libInfo);761 762} // end namespace Mips763 764} // end namespace llvm765 766#endif // LLVM_LIB_TARGET_MIPS_MIPSISELLOWERING_H767