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