brintos

brintos / llvm-project-archived public Read only

0
0
Text · 32.5 KiB · 8191eb4 Raw
741 lines · c
1//===- ARMISelLowering.h - ARM 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 ARM uses to lower LLVM code into a10// selection DAG.11//12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_LIB_TARGET_ARM_ARMISELLOWERING_H15#define LLVM_LIB_TARGET_ARM_ARMISELLOWERING_H16 17#include "MCTargetDesc/ARMBaseInfo.h"18#include "llvm/ADT/SmallVector.h"19#include "llvm/ADT/StringRef.h"20#include "llvm/CodeGen/CallingConvLower.h"21#include "llvm/CodeGen/ISDOpcodes.h"22#include "llvm/CodeGen/MachineFunction.h"23#include "llvm/CodeGen/SelectionDAGNodes.h"24#include "llvm/CodeGen/TargetLowering.h"25#include "llvm/CodeGen/ValueTypes.h"26#include "llvm/CodeGenTypes/MachineValueType.h"27#include "llvm/IR/Attributes.h"28#include "llvm/IR/CallingConv.h"29#include "llvm/IR/Function.h"30#include "llvm/IR/InlineAsm.h"31#include "llvm/Support/CodeGen.h"32#include <optional>33#include <utility>34 35namespace llvm {36 37class ARMBaseTargetMachine;38class ARMSubtarget;39class DataLayout;40class FastISel;41class FunctionLoweringInfo;42class GlobalValue;43class InstrItineraryData;44class Instruction;45class IRBuilderBase;46class MachineBasicBlock;47class MachineInstr;48class SelectionDAG;49class TargetLibraryInfo;50class TargetMachine;51class TargetRegisterInfo;52class VectorType;53 54  namespace ARM {55  /// Possible values of current rounding mode, which is specified in bits56  /// 23:22 of FPSCR.57  enum Rounding {58    RN = 0,    // Round to Nearest59    RP = 1,    // Round towards Plus infinity60    RM = 2,    // Round towards Minus infinity61    RZ = 3,    // Round towards Zero62    rmMask = 3 // Bit mask selecting rounding mode63  };64 65  // Bit position of rounding mode bits in FPSCR.66  const unsigned RoundingBitsPos = 22;67 68  // Bits of floating-point status. These are NZCV flags, QC bit and cumulative69  // FP exception bits.70  const unsigned FPStatusBits = 0xf800009f;71 72  // Some bits in the FPSCR are not yet defined.  They must be preserved when73  // modifying the contents.74  const unsigned FPReservedBits = 0x00006060;75  } // namespace ARM76 77  /// Define some predicates that are used for node matching.78  namespace ARM {79 80    bool isBitFieldInvertedMask(unsigned v);81 82  } // end namespace ARM83 84  //===--------------------------------------------------------------------===//85  //  ARMTargetLowering - ARM Implementation of the TargetLowering interface86 87  class ARMTargetLowering : public TargetLowering {88    // Copying needed for an outgoing byval argument.89    enum ByValCopyKind {90      // Argument is already in the correct location, no copy needed.91      NoCopy,92      // Argument value is currently in the local stack frame, needs copying to93      // outgoing arguemnt area.94      CopyOnce,95      // Argument value is currently in the outgoing argument area, but not at96      // the correct offset, so needs copying via a temporary in local stack97      // space.98      CopyViaTemp,99    };100 101  public:102    explicit ARMTargetLowering(const TargetMachine &TM,103                               const ARMSubtarget &STI);104 105    const ARMBaseTargetMachine &getTM() const;106 107    unsigned getJumpTableEncoding() const override;108    bool useSoftFloat() const override;109 110    SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;111 112    /// ReplaceNodeResults - Replace the results of node with an illegal result113    /// type with new values built out of custom code.114    void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,115                            SelectionDAG &DAG) const override;116 117    bool isSelectSupported(SelectSupportKind Kind) const override {118      // ARM does not support scalar condition selects on vectors.119      return (Kind != ScalarCondVectorVal);120    }121 122    bool isReadOnly(const GlobalValue *GV) const;123 124    /// getSetCCResultType - Return the value type to use for ISD::SETCC.125    EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,126                           EVT VT) const override;127 128    MachineBasicBlock *129    EmitInstrWithCustomInserter(MachineInstr &MI,130                                MachineBasicBlock *MBB) const override;131 132    void AdjustInstrPostInstrSelection(MachineInstr &MI,133                                       SDNode *Node) const override;134 135    bool supportKCFIBundles() const override;136 137    MachineInstr *EmitKCFICheck(MachineBasicBlock &MBB,138                                MachineBasicBlock::instr_iterator &MBBI,139                                const TargetInstrInfo *TII) const override;140 141    SDValue PerformCMOVCombine(SDNode *N, SelectionDAG &DAG) const;142    SDValue PerformBRCONDCombine(SDNode *N, SelectionDAG &DAG) const;143    SDValue PerformCMOVToBFICombine(SDNode *N, SelectionDAG &DAG) const;144    SDValue PerformIntrinsicCombine(SDNode *N, DAGCombinerInfo &DCI) const;145    SDValue PerformMVEExtCombine(SDNode *N, DAGCombinerInfo &DCI) const;146    SDValue PerformMVETruncCombine(SDNode *N, DAGCombinerInfo &DCI) const;147    SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;148 149    bool SimplifyDemandedBitsForTargetNode(SDValue Op,150                                           const APInt &OriginalDemandedBits,151                                           const APInt &OriginalDemandedElts,152                                           KnownBits &Known,153                                           TargetLoweringOpt &TLO,154                                           unsigned Depth) const override;155 156    bool isDesirableToTransformToIntegerOp(unsigned Opc, EVT VT) const override;157 158    /// allowsMisalignedMemoryAccesses - Returns true if the target allows159    /// unaligned memory accesses of the specified type. Returns whether it160    /// is "fast" by reference in the second argument.161    bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace,162                                        Align Alignment,163                                        MachineMemOperand::Flags Flags,164                                        unsigned *Fast) const override;165 166    EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,167                            const AttributeList &FuncAttributes) const override;168 169    bool isTruncateFree(Type *SrcTy, Type *DstTy) const override;170    bool isTruncateFree(EVT SrcVT, EVT DstVT) const override;171    bool isZExtFree(SDValue Val, EVT VT2) const override;172    Type* shouldConvertSplatType(ShuffleVectorInst* SVI) const override;173 174    bool isFNegFree(EVT VT) const override;175 176    bool isVectorLoadExtDesirable(SDValue ExtVal) const override;177 178    bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override;179 180 181    /// isLegalAddressingMode - Return true if the addressing mode represented182    /// by AM is legal for this target, for a load/store of the specified type.183    bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,184                               Type *Ty, unsigned AS,185                               Instruction *I = nullptr) const override;186 187    bool isLegalT2ScaledAddressingMode(const AddrMode &AM, EVT VT) const;188 189    /// Returns true if the addressing mode representing by AM is legal190    /// for the Thumb1 target, for a load/store of the specified type.191    bool isLegalT1ScaledAddressingMode(const AddrMode &AM, EVT VT) const;192 193    /// isLegalICmpImmediate - Return true if the specified immediate is legal194    /// icmp immediate, that is the target has icmp instructions which can195    /// compare a register against the immediate without having to materialize196    /// the immediate into a register.197    bool isLegalICmpImmediate(int64_t Imm) const override;198 199    /// isLegalAddImmediate - Return true if the specified immediate is legal200    /// add immediate, that is the target has add instructions which can201    /// add a register and the immediate without having to materialize202    /// the immediate into a register.203    bool isLegalAddImmediate(int64_t Imm) const override;204 205    /// getPreIndexedAddressParts - returns true by value, base pointer and206    /// offset pointer and addressing mode by reference if the node's address207    /// can be legally represented as pre-indexed load / store address.208    bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset,209                                   ISD::MemIndexedMode &AM,210                                   SelectionDAG &DAG) const override;211 212    /// getPostIndexedAddressParts - returns true by value, base pointer and213    /// offset pointer and addressing mode by reference if this node can be214    /// combined with a load / store to form a post-indexed load / store.215    bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, SDValue &Base,216                                    SDValue &Offset, ISD::MemIndexedMode &AM,217                                    SelectionDAG &DAG) const override;218 219    void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known,220                                       const APInt &DemandedElts,221                                       const SelectionDAG &DAG,222                                       unsigned Depth) const override;223 224    bool targetShrinkDemandedConstant(SDValue Op, const APInt &DemandedBits,225                                      const APInt &DemandedElts,226                                      TargetLoweringOpt &TLO) const override;227 228    ConstraintType getConstraintType(StringRef Constraint) const override;229 230    /// Examine constraint string and operand type and determine a weight value.231    /// The operand object must already have been set up with the operand type.232    ConstraintWeight getSingleConstraintMatchWeight(233      AsmOperandInfo &info, const char *constraint) const override;234 235    std::pair<unsigned, const TargetRegisterClass *>236    getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,237                                 StringRef Constraint, MVT VT) const override;238 239    const char *LowerXConstraint(EVT ConstraintVT) const override;240 241    /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops242    /// vector.  If it is invalid, don't add anything to Ops. If hasMemory is243    /// true it means one of the asm constraint of the inline asm instruction244    /// being processed is 'm'.245    void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint,246                                      std::vector<SDValue> &Ops,247                                      SelectionDAG &DAG) const override;248 249    InlineAsm::ConstraintCode250    getInlineAsmMemConstraint(StringRef ConstraintCode) const override {251      if (ConstraintCode == "Q")252        return InlineAsm::ConstraintCode::Q;253      if (ConstraintCode.size() == 2) {254        if (ConstraintCode[0] == 'U') {255          switch(ConstraintCode[1]) {256          default:257            break;258          case 'm':259            return InlineAsm::ConstraintCode::Um;260          case 'n':261            return InlineAsm::ConstraintCode::Un;262          case 'q':263            return InlineAsm::ConstraintCode::Uq;264          case 's':265            return InlineAsm::ConstraintCode::Us;266          case 't':267            return InlineAsm::ConstraintCode::Ut;268          case 'v':269            return InlineAsm::ConstraintCode::Uv;270          case 'y':271            return InlineAsm::ConstraintCode::Uy;272          }273        }274      }275      return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);276    }277 278    const ARMSubtarget* getSubtarget() const {279      return Subtarget;280    }281 282    /// getRegClassFor - Return the register class that should be used for the283    /// specified value type.284    const TargetRegisterClass *285    getRegClassFor(MVT VT, bool isDivergent = false) const override;286 287    bool shouldAlignPointerArgs(CallInst *CI, unsigned &MinSize,288                                Align &PrefAlign) const override;289 290    /// createFastISel - This method returns a target specific FastISel object,291    /// or null if the target does not support "fast" ISel.292    FastISel *createFastISel(FunctionLoweringInfo &funcInfo,293                             const TargetLibraryInfo *libInfo) const override;294 295    Sched::Preference getSchedulingPreference(SDNode *N) const override;296 297    bool preferZeroCompareBranch() const override { return true; }298 299    bool preferSelectsOverBooleanArithmetic(EVT VT) const override;300 301    bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override;302 303    bool hasAndNotCompare(SDValue V) const override {304      // We can use bics for any scalar.305      return V.getValueType().isScalarInteger();306    }307 308    bool309    isShuffleMaskLegal(ArrayRef<int> M, EVT VT) const override;310    bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;311 312    /// isFPImmLegal - Returns true if the target can instruction select the313    /// specified FP immediate natively. If false, the legalizer will314    /// materialize the FP immediate as a load from a constant pool.315    bool isFPImmLegal(const APFloat &Imm, EVT VT,316                      bool ForCodeSize = false) const override;317 318    bool getTgtMemIntrinsic(IntrinsicInfo &Info,319                            const CallInst &I,320                            MachineFunction &MF,321                            unsigned Intrinsic) const override;322 323    /// Returns true if it is beneficial to convert a load of a constant324    /// to just the constant itself.325    bool shouldConvertConstantLoadToIntImm(const APInt &Imm,326                                           Type *Ty) const override;327 328    /// Return true if EXTRACT_SUBVECTOR is cheap for this result type329    /// with this index.330    bool isExtractSubvectorCheap(EVT ResVT, EVT SrcVT,331                                 unsigned Index) const override;332 333    bool shouldFormOverflowOp(unsigned Opcode, EVT VT,334                              bool MathUsed) const override {335      // Using overflow ops for overflow checks only should beneficial on ARM.336      return TargetLowering::shouldFormOverflowOp(Opcode, VT, true);337    }338 339    bool shouldReassociateReduction(unsigned Opc, EVT VT) const override {340      return Opc != ISD::VECREDUCE_ADD;341    }342 343    /// Returns true if an argument of type Ty needs to be passed in a344    /// contiguous block of registers in calling convention CallConv.345    bool functionArgumentNeedsConsecutiveRegisters(346        Type *Ty, CallingConv::ID CallConv, bool isVarArg,347        const DataLayout &DL) const override;348 349    /// If a physical register, this returns the register that receives the350    /// exception address on entry to an EH pad.351    Register352    getExceptionPointerRegister(const Constant *PersonalityFn) const override;353 354    /// If a physical register, this returns the register that receives the355    /// exception typeid on entry to a landing pad.356    Register357    getExceptionSelectorRegister(const Constant *PersonalityFn) const override;358 359    Instruction *makeDMB(IRBuilderBase &Builder, ARM_MB::MemBOpt Domain) const;360    Value *emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr,361                          AtomicOrdering Ord) const override;362    Value *emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr,363                                AtomicOrdering Ord) const override;364 365    void366    emitAtomicCmpXchgNoStoreLLBalance(IRBuilderBase &Builder) const override;367 368    Instruction *emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst,369                                  AtomicOrdering Ord) const override;370    Instruction *emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst,371                                   AtomicOrdering Ord) const override;372 373    unsigned getMaxSupportedInterleaveFactor() const override;374 375    bool lowerInterleavedLoad(Instruction *Load, Value *Mask,376                              ArrayRef<ShuffleVectorInst *> Shuffles,377                              ArrayRef<unsigned> Indices, unsigned Factor,378                              const APInt &GapMask) const override;379    bool lowerInterleavedStore(Instruction *Store, Value *Mask,380                               ShuffleVectorInst *SVI, unsigned Factor,381                               const APInt &GapMask) const override;382 383    bool shouldInsertFencesForAtomic(const Instruction *I) const override;384    TargetLoweringBase::AtomicExpansionKind385    shouldExpandAtomicLoadInIR(LoadInst *LI) const override;386    TargetLoweringBase::AtomicExpansionKind387    shouldExpandAtomicStoreInIR(StoreInst *SI) const override;388    TargetLoweringBase::AtomicExpansionKind389    shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override;390    TargetLoweringBase::AtomicExpansionKind391    shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override;392 393    bool useLoadStackGuardNode(const Module &M) const override;394 395    void insertSSPDeclarations(Module &M) const override;396 397    bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx,398                                   unsigned &Cost) const override;399 400    bool canCreateUndefOrPoisonForTargetNode(401        SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,402        bool PoisonOnly, bool ConsiderFlags, unsigned Depth) const override;403 404    bool canMergeStoresTo(unsigned AddressSpace, EVT MemVT,405                          const MachineFunction &MF) const override {406      // Do not merge to larger than i32.407      return (MemVT.getSizeInBits() <= 32);408    }409 410    bool isCheapToSpeculateCttz(Type *Ty) const override;411    bool isCheapToSpeculateCtlz(Type *Ty) const override;412 413    bool convertSetCCLogicToBitwiseLogic(EVT VT) const override {414      return VT.isScalarInteger();415    }416 417    bool supportSwiftError() const override {418      return true;419    }420 421    bool supportSplitCSR(MachineFunction *MF) const override {422      return MF->getFunction().getCallingConv() == CallingConv::CXX_FAST_TLS &&423             MF->getFunction().hasFnAttribute(Attribute::NoUnwind);424    }425 426    bool hasStandaloneRem(EVT VT) const override {427      return HasStandaloneRem;428    }429 430    ShiftLegalizationStrategy431    preferredShiftLegalizationStrategy(SelectionDAG &DAG, SDNode *N,432                                       unsigned ExpansionFactor) const override;433 434    CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool isVarArg) const;435    CCAssignFn *CCAssignFnForReturn(CallingConv::ID CC, bool isVarArg) const;436 437    /// Returns true if \p VecTy is a legal interleaved access type. This438    /// function checks the vector element type and the overall width of the439    /// vector.440    bool isLegalInterleavedAccessType(unsigned Factor, FixedVectorType *VecTy,441                                      Align Alignment,442                                      const DataLayout &DL) const;443 444    bool isMulAddWithConstProfitable(SDValue AddNode,445                                     SDValue ConstNode) const override;446 447    bool alignLoopsWithOptSize() const override;448 449    /// Returns the number of interleaved accesses that will be generated when450    /// lowering accesses of the given type.451    unsigned getNumInterleavedAccesses(VectorType *VecTy,452                                       const DataLayout &DL) const;453 454    void finalizeLowering(MachineFunction &MF) const override;455 456    /// Return the correct alignment for the current calling convention.457    Align getABIAlignmentForCallingConv(Type *ArgTy,458                                        const DataLayout &DL) const override;459 460    bool isDesirableToCommuteWithShift(const SDNode *N,461                                       CombineLevel Level) const override;462 463    bool isDesirableToCommuteXorWithShift(const SDNode *N) const override;464 465    bool shouldFoldConstantShiftPairToMask(const SDNode *N) const override;466 467    /// Return true if it is profitable to fold a pair of shifts into a mask.468    bool shouldFoldMaskToVariableShiftPair(SDValue Y) const override {469      EVT VT = Y.getValueType();470 471      if (VT.isVector())472        return false;473 474      return VT.getScalarSizeInBits() <= 32;475    }476 477    bool shouldFoldSelectWithIdentityConstant(unsigned BinOpcode, EVT VT,478                                              unsigned SelectOpcode, SDValue X,479                                              SDValue Y) const override;480 481    bool preferIncOfAddToSubOfNot(EVT VT) const override;482 483    bool shouldConvertFpToSat(unsigned Op, EVT FPVT, EVT VT) const override;484 485    bool isComplexDeinterleavingSupported() const override;486    bool isComplexDeinterleavingOperationSupported(487        ComplexDeinterleavingOperation Operation, Type *Ty) const override;488 489    Value *createComplexDeinterleavingIR(490        IRBuilderBase &B, ComplexDeinterleavingOperation OperationType,491        ComplexDeinterleavingRotation Rotation, Value *InputA, Value *InputB,492        Value *Accumulator = nullptr) const override;493 494    bool softPromoteHalfType() const override { return true; }495 496    bool useFPRegsForHalfType() const override { return true; }497 498  protected:499    std::pair<const TargetRegisterClass *, uint8_t>500    findRepresentativeClass(const TargetRegisterInfo *TRI,501                            MVT VT) const override;502 503  private:504    /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can505    /// make the right decision when generating code for different targets.506    const ARMSubtarget *Subtarget;507 508    const TargetRegisterInfo *RegInfo;509 510    const InstrItineraryData *Itins;511 512    // TODO: remove this, and have shouldInsertFencesForAtomic do the proper513    // check.514    bool InsertFencesForAtomic;515 516    bool HasStandaloneRem = true;517 518    void addTypeForNEON(MVT VT, MVT PromotedLdStVT);519    void addDRTypeForNEON(MVT VT);520    void addQRTypeForNEON(MVT VT);521    std::pair<SDValue, SDValue> getARMXALUOOp(SDValue Op, SelectionDAG &DAG, SDValue &ARMcc) const;522 523    using RegsToPassVector = SmallVector<std::pair<unsigned, SDValue>, 8>;524 525    void PassF64ArgInRegs(const SDLoc &dl, SelectionDAG &DAG, SDValue Chain,526                          SDValue &Arg, RegsToPassVector &RegsToPass,527                          CCValAssign &VA, CCValAssign &NextVA,528                          SDValue &StackPtr,529                          SmallVectorImpl<SDValue> &MemOpChains,530                          bool IsTailCall,531                          int SPDiff) const;532    SDValue GetF64FormalArgument(CCValAssign &VA, CCValAssign &NextVA,533                                 SDValue &Root, SelectionDAG &DAG,534                                 const SDLoc &dl) const;535 536    CallingConv::ID getEffectiveCallingConv(CallingConv::ID CC,537                                            bool isVarArg) const;538    CCAssignFn *CCAssignFnForNode(CallingConv::ID CC, bool Return,539                                  bool isVarArg) const;540    std::pair<SDValue, MachinePointerInfo>541    computeAddrForCallArg(const SDLoc &dl, SelectionDAG &DAG,542                          const CCValAssign &VA, SDValue StackPtr,543                          bool IsTailCall, int SPDiff) const;544    ByValCopyKind ByValNeedsCopyForTailCall(SelectionDAG &DAG, SDValue Src,545                                            SDValue Dst,546                                            ISD::ArgFlagsTy Flags) const;547    SDValue LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;548    SDValue LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;549    SDValue LowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const;550    SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG,551                                    const ARMSubtarget *Subtarget) const;552    SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,553                                    const ARMSubtarget *Subtarget) const;554    SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;555    SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;556    SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;557    SDValue LowerGlobalAddressDarwin(SDValue Op, SelectionDAG &DAG) const;558    SDValue LowerGlobalAddressELF(SDValue Op, SelectionDAG &DAG) const;559    SDValue LowerGlobalAddressWindows(SDValue Op, SelectionDAG &DAG) const;560    SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;561    SDValue LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,562                                            SelectionDAG &DAG) const;563    SDValue LowerToTLSExecModels(GlobalAddressSDNode *GA,564                                 SelectionDAG &DAG,565                                 TLSModel::Model model) const;566    SDValue LowerGlobalTLSAddressDarwin(SDValue Op, SelectionDAG &DAG) const;567    SDValue LowerGlobalTLSAddressWindows(SDValue Op, SelectionDAG &DAG) const;568    SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const;569    SDValue LowerSignedALUO(SDValue Op, SelectionDAG &DAG) const;570    SDValue LowerUnsignedALUO(SDValue Op, SelectionDAG &DAG) const;571    SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const;572    SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;573    SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const;574    SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;575    SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const;576    SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;577    SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;578    SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG) const;579    SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;580    SDValue LowerGET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;581    SDValue LowerSET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;582    SDValue LowerSET_FPMODE(SDValue Op, SelectionDAG &DAG) const;583    SDValue LowerRESET_FPMODE(SDValue Op, SelectionDAG &DAG) const;584    SDValue LowerConstantFP(SDValue Op, SelectionDAG &DAG,585                            const ARMSubtarget *ST) const;586    SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,587                              const ARMSubtarget *ST) const;588    SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;589    SDValue LowerDivRem(SDValue Op, SelectionDAG &DAG) const;590    SDValue LowerDIV_Windows(SDValue Op, SelectionDAG &DAG, bool Signed) const;591    void ExpandDIV_Windows(SDValue Op, SelectionDAG &DAG, bool Signed,592                           SmallVectorImpl<SDValue> &Results) const;593    SDValue ExpandBITCAST(SDNode *N, SelectionDAG &DAG,594                          const ARMSubtarget *Subtarget) const;595    SDValue LowerWindowsDIVLibCall(SDValue Op, SelectionDAG &DAG, bool Signed,596                                   SDValue &Chain) const;597    SDValue LowerREM(SDNode *N, SelectionDAG &DAG) const;598    SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;599    SDValue LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const;600    SDValue LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const;601    SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const;602    SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;603    SDValue LowerFSETCC(SDValue Op, SelectionDAG &DAG) const;604    SDValue LowerSPONENTRY(SDValue Op, SelectionDAG &DAG) const;605    void LowerLOAD(SDNode *N, SmallVectorImpl<SDValue> &Results,606                   SelectionDAG &DAG) const;607    SDValue LowerFP_TO_BF16(SDValue Op, SelectionDAG &DAG) const;608    SDValue LowerCMP(SDValue Op, SelectionDAG &DAG) const;609    SDValue LowerABS(SDValue Op, SelectionDAG &DAG) const;610 611    Register getRegisterByName(const char* RegName, LLT VT,612                               const MachineFunction &MF) const override;613 614    SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG,615                          SmallVectorImpl<SDNode *> &Created) const override;616 617    bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,618                                    EVT VT) const override;619 620    SDValue MoveToHPR(const SDLoc &dl, SelectionDAG &DAG, MVT LocVT, MVT ValVT,621                      SDValue Val) const;622    SDValue MoveFromHPR(const SDLoc &dl, SelectionDAG &DAG, MVT LocVT,623                        MVT ValVT, SDValue Val) const;624 625    SDValue ReconstructShuffle(SDValue Op, SelectionDAG &DAG) const;626 627    SDValue LowerCallResult(SDValue Chain, SDValue InGlue,628                            CallingConv::ID CallConv, bool isVarArg,629                            const SmallVectorImpl<ISD::InputArg> &Ins,630                            const SDLoc &dl, SelectionDAG &DAG,631                            SmallVectorImpl<SDValue> &InVals, bool isThisReturn,632                            SDValue ThisVal, bool isCmseNSCall) const;633 634    void initializeSplitCSR(MachineBasicBlock *Entry) const override;635    void insertCopiesSplitCSR(636      MachineBasicBlock *Entry,637      const SmallVectorImpl<MachineBasicBlock *> &Exits) const override;638 639    bool splitValueIntoRegisterParts(640        SelectionDAG & DAG, const SDLoc &DL, SDValue Val, SDValue *Parts,641        unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC)642        const override;643 644    SDValue joinRegisterPartsIntoValue(645        SelectionDAG & DAG, const SDLoc &DL, const SDValue *Parts,646        unsigned NumParts, MVT PartVT, EVT ValueVT,647        std::optional<CallingConv::ID> CC) const override;648 649    SDValue650    LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,651                         const SmallVectorImpl<ISD::InputArg> &Ins,652                         const SDLoc &dl, SelectionDAG &DAG,653                         SmallVectorImpl<SDValue> &InVals) const override;654 655    int StoreByValRegs(CCState &CCInfo, SelectionDAG &DAG, const SDLoc &dl,656                       SDValue &Chain, const Value *OrigArg,657                       unsigned InRegsParamRecordIdx, int ArgOffset,658                       unsigned ArgSize) const;659 660    void VarArgStyleRegisters(CCState &CCInfo, SelectionDAG &DAG,661                              const SDLoc &dl, SDValue &Chain,662                              unsigned ArgOffset, unsigned TotalArgRegsSaveSize,663                              bool ForceMutable = false) const;664 665    SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,666                      SmallVectorImpl<SDValue> &InVals) const override;667 668    /// HandleByVal - Target-specific cleanup for ByVal support.669    void HandleByVal(CCState *, unsigned &, Align) const override;670 671    /// IsEligibleForTailCallOptimization - Check whether the call is eligible672    /// for tail call optimization. Targets which want to do tail call673    /// optimization should implement this function.674    bool IsEligibleForTailCallOptimization(675        TargetLowering::CallLoweringInfo &CLI, CCState &CCInfo,676        SmallVectorImpl<CCValAssign> &ArgLocs, const bool isIndirect) const;677 678    bool CanLowerReturn(CallingConv::ID CallConv,679                        MachineFunction &MF, bool isVarArg,680                        const SmallVectorImpl<ISD::OutputArg> &Outs,681                        LLVMContext &Context, const Type *RetTy) const override;682 683    SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,684                        const SmallVectorImpl<ISD::OutputArg> &Outs,685                        const SmallVectorImpl<SDValue> &OutVals,686                        const SDLoc &dl, SelectionDAG &DAG) const override;687 688    bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override;689 690    bool mayBeEmittedAsTailCall(const CallInst *CI) const override;691 692    bool shouldConsiderGEPOffsetSplit() const override { return true; }693 694    bool isUnsupportedFloatingType(EVT VT) const;695 696    ArrayRef<MCPhysReg> getRoundingControlRegisters() const override;697 698    SDValue getCMOV(const SDLoc &dl, EVT VT, SDValue FalseVal, SDValue TrueVal,699                    SDValue ARMcc, SDValue Flags, SelectionDAG &DAG) const;700    SDValue getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,701                      SDValue &ARMcc, SelectionDAG &DAG, const SDLoc &dl) const;702    SDValue getVFPCmp(SDValue LHS, SDValue RHS, SelectionDAG &DAG,703                      const SDLoc &dl, bool Signaling = false) const;704 705    SDValue OptimizeVFPBrcond(SDValue Op, SelectionDAG &DAG) const;706 707    void SetupEntryBlockForSjLj(MachineInstr &MI, MachineBasicBlock *MBB,708                                MachineBasicBlock *DispatchBB, int FI) const;709 710    void EmitSjLjDispatchBlock(MachineInstr &MI, MachineBasicBlock *MBB) const;711 712    MachineBasicBlock *EmitStructByval(MachineInstr &MI,713                                       MachineBasicBlock *MBB) const;714 715    MachineBasicBlock *EmitLowered__chkstk(MachineInstr &MI,716                                           MachineBasicBlock *MBB) const;717    MachineBasicBlock *EmitLowered__dbzchk(MachineInstr &MI,718                                           MachineBasicBlock *MBB) const;719    void addMVEVectorTypes(bool HasMVEFP);720    void addAllExtLoads(const MVT From, const MVT To, LegalizeAction Action);721    void setAllExpand(MVT VT);722  };723 724  enum VMOVModImmType {725    VMOVModImm,726    VMVNModImm,727    MVEVMVNModImm,728    OtherModImm729  };730 731  namespace ARM {732 733    FastISel *createFastISel(FunctionLoweringInfo &funcInfo,734                             const TargetLibraryInfo *libInfo);735 736  } // end namespace ARM737 738} // end namespace llvm739 740#endif // LLVM_LIB_TARGET_ARM_ARMISELLOWERING_H741