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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the interfaces that ARM uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_TARGET_ARM_ARMISELLOWERING_H
15#define LLVM_LIB_TARGET_ARM_ARMISELLOWERING_H
16
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 bits
56 /// 23:22 of FPSCR.
57 enum Rounding {
58 RN = 0, // Round to Nearest
59 RP = 1, // Round towards Plus infinity
60 RM = 2, // Round towards Minus infinity
61 RZ = 3, // Round towards Zero
62 rmMask = 3 // Bit mask selecting rounding mode
63 };
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 cumulative
69 // FP exception bits.
70 const unsigned FPStatusBits = 0xf800009f;
71
72 // Some bits in the FPSCR are not yet defined. They must be preserved when
73 // modifying the contents.
74 const unsigned FPReservedBits = 0x00006060;
75 } // namespace ARM
76
77 /// Define some predicates that are used for node matching.
78 namespace ARM {
79
80 bool isBitFieldInvertedMask(unsigned v);
81
82 } // end namespace ARM
83
84 //===--------------------------------------------------------------------===//
85 // ARMTargetLowering - ARM Implementation of the TargetLowering interface
86
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 to
93 // outgoing arguemnt area.
94 CopyOnce,
95 // Argument value is currently in the outgoing argument area, but not at
96 // the correct offset, so needs copying via a temporary in local stack
97 // 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 result
113 /// 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 allows
159 /// unaligned memory accesses of the specified type. Returns whether it
160 /// 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 represented
182 /// 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 legal
190 /// 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 legal
194 /// icmp immediate, that is the target has icmp instructions which can
195 /// compare a register against the immediate without having to materialize
196 /// the immediate into a register.
197 bool isLegalICmpImmediate(int64_t Imm) const override;
198
199 /// isLegalAddImmediate - Return true if the specified immediate is legal
200 /// add immediate, that is the target has add instructions which can
201 /// add a register and the immediate without having to materialize
202 /// the immediate into a register.
203 bool isLegalAddImmediate(int64_t Imm) const override;
204
205 /// getPreIndexedAddressParts - returns true by value, base pointer and
206 /// offset pointer and addressing mode by reference if the node's address
207 /// 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 and
213 /// offset pointer and addressing mode by reference if this node can be
214 /// 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 Ops
242 /// vector. If it is invalid, don't add anything to Ops. If hasMemory is
243 /// true it means one of the asm constraint of the inline asm instruction
244 /// being processed is 'm'.
245 void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint,
246 std::vector<SDValue> &Ops,
247 SelectionDAG &DAG) const override;
248
249 InlineAsm::ConstraintCode
250 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 the
283 /// 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 *
293 createFastISel(FunctionLoweringInfo &funcInfo,
294 const TargetLibraryInfo *libInfo,
295 const LibcallLoweringInfo *libcallLowering) const override;
296
297 Sched::Preference getSchedulingPreference(SDNode *N) const override;
298
299 bool preferZeroCompareBranch() const override { return true; }
300
301 bool preferSelectsOverBooleanArithmetic(EVT VT) const override;
302
303 bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override;
304
305 bool hasAndNotCompare(SDValue V) const override {
306 // We can use bics for any scalar.
307 return V.getValueType().isScalarInteger();
308 }
309
310 bool
311 isShuffleMaskLegal(ArrayRef<int> M, EVT VT) const override;
312 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
313
314 /// isFPImmLegal - Returns true if the target can instruction select the
315 /// specified FP immediate natively. If false, the legalizer will
316 /// materialize the FP immediate as a load from a constant pool.
317 bool isFPImmLegal(const APFloat &Imm, EVT VT,
318 bool ForCodeSize = false) const override;
319
320 void getTgtMemIntrinsic(SmallVectorImpl<IntrinsicInfo> &Infos,
321 const CallBase &I, MachineFunction &MF,
322 unsigned Intrinsic) const override;
323
324 /// Returns true if it is beneficial to convert a load of a constant
325 /// to just the constant itself.
326 bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
327 Type *Ty) const override;
328
329 /// Return true if EXTRACT_SUBVECTOR is cheap for this result type
330 /// with this index.
331 bool isExtractSubvectorCheap(EVT ResVT, EVT SrcVT,
332 unsigned Index) const override;
333
334 bool shouldFormOverflowOp(unsigned Opcode, EVT VT,
335 bool MathUsed) const override {
336 // Using overflow ops for overflow checks only should beneficial on ARM.
337 return TargetLowering::shouldFormOverflowOp(Opcode, VT, MathUsed: true);
338 }
339
340 bool shouldReassociateReduction(unsigned Opc, EVT VT) const override {
341 return Opc != ISD::VECREDUCE_ADD;
342 }
343
344 /// Returns true if an argument of type Ty needs to be passed in a
345 /// contiguous block of registers in calling convention CallConv.
346 bool functionArgumentNeedsConsecutiveRegisters(
347 Type *Ty, CallingConv::ID CallConv, bool isVarArg,
348 const DataLayout &DL) const override;
349
350 /// If a physical register, this returns the register that receives the
351 /// exception address on entry to an EH pad.
352 Register
353 getExceptionPointerRegister(const Constant *PersonalityFn) const override;
354
355 /// If a physical register, this returns the register that receives the
356 /// exception typeid on entry to a landing pad.
357 Register
358 getExceptionSelectorRegister(const Constant *PersonalityFn) const override;
359
360 Instruction *makeDMB(IRBuilderBase &Builder, ARM_MB::MemBOpt Domain) const;
361 Value *emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr,
362 AtomicOrdering Ord) const override;
363 Value *emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr,
364 AtomicOrdering Ord) const override;
365
366 void
367 emitAtomicCmpXchgNoStoreLLBalance(IRBuilderBase &Builder) const override;
368
369 Instruction *emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst,
370 AtomicOrdering Ord) const override;
371 Instruction *emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst,
372 AtomicOrdering Ord) const override;
373
374 unsigned getMaxSupportedInterleaveFactor() const override;
375
376 bool lowerInterleavedLoad(Instruction *Load, Value *Mask,
377 ArrayRef<ShuffleVectorInst *> Shuffles,
378 ArrayRef<unsigned> Indices, unsigned Factor,
379 const APInt &GapMask) const override;
380 bool lowerInterleavedStore(Instruction *Store, Value *Mask,
381 ShuffleVectorInst *SVI, unsigned Factor,
382 const APInt &GapMask) const override;
383
384 bool shouldInsertFencesForAtomic(const Instruction *I) const override;
385 TargetLoweringBase::AtomicExpansionKind
386 shouldExpandAtomicLoadInIR(LoadInst *LI) const override;
387 TargetLoweringBase::AtomicExpansionKind
388 shouldExpandAtomicStoreInIR(StoreInst *SI) const override;
389 TargetLoweringBase::AtomicExpansionKind
390 shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const override;
391 TargetLoweringBase::AtomicExpansionKind
392 shouldExpandAtomicCmpXchgInIR(const AtomicCmpXchgInst *AI) const override;
393
394 bool useLoadStackGuardNode(const Module &M) const override;
395
396 void
397 insertSSPDeclarations(Module &M,
398 const LibcallLoweringInfo &Libcalls) const override;
399
400 bool canCombineStoreAndExtract(Type *VectorTy, Value *Idx,
401 unsigned &Cost) const override;
402
403 bool canCreateUndefOrPoisonForTargetNode(
404 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
405 bool PoisonOnly, bool ConsiderFlags, unsigned Depth) const override;
406
407 bool canMergeStoresTo(unsigned AddressSpace, EVT MemVT,
408 const MachineFunction &MF) const override {
409 // Do not merge to larger than i32.
410 return (MemVT.getSizeInBits() <= 32);
411 }
412
413 bool isCheapToSpeculateCttz(Type *Ty) const override;
414 bool isCheapToSpeculateCtlz(Type *Ty) const override;
415
416 bool convertSetCCLogicToBitwiseLogic(EVT VT) const override {
417 return VT.isScalarInteger();
418 }
419
420 bool supportSwiftError() const override {
421 return true;
422 }
423
424 bool supportSplitCSR(MachineFunction *MF) const override {
425 return MF->getFunction().getCallingConv() == CallingConv::CXX_FAST_TLS &&
426 MF->getFunction().hasFnAttribute(Kind: Attribute::NoUnwind);
427 }
428
429 bool hasStandaloneRem(EVT VT) const override {
430 return HasStandaloneRem;
431 }
432
433 ShiftLegalizationStrategy
434 preferredShiftLegalizationStrategy(SelectionDAG &DAG, SDNode *N,
435 unsigned ExpansionFactor) const override;
436
437 CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool isVarArg) const;
438 CCAssignFn *CCAssignFnForReturn(CallingConv::ID CC, bool isVarArg) const;
439
440 /// Returns true if \p VecTy is a legal interleaved access type. This
441 /// function checks the vector element type and the overall width of the
442 /// vector.
443 bool isLegalInterleavedAccessType(unsigned Factor, FixedVectorType *VecTy,
444 Align Alignment,
445 const DataLayout &DL) const;
446
447 bool isMulAddWithConstProfitable(SDValue AddNode,
448 SDValue ConstNode) const override;
449
450 bool alignLoopsWithOptSize() const override;
451
452 /// Returns the number of interleaved accesses that will be generated when
453 /// lowering accesses of the given type.
454 unsigned getNumInterleavedAccesses(VectorType *VecTy,
455 const DataLayout &DL) const;
456
457 void finalizeLowering(MachineFunction &MF) const override;
458
459 /// Return the correct alignment for the current calling convention.
460 Align getABIAlignmentForCallingConv(Type *ArgTy,
461 const DataLayout &DL) const override;
462
463 bool isDesirableToCommuteWithShift(const SDNode *N,
464 CombineLevel Level) const override;
465
466 bool isDesirableToCommuteXorWithShift(const SDNode *N) const override;
467
468 bool shouldFoldConstantShiftPairToMask(const SDNode *N) const override;
469
470 /// Return true if it is profitable to fold a pair of shifts into a mask.
471 bool shouldFoldMaskToVariableShiftPair(SDValue Y) const override {
472 EVT VT = Y.getValueType();
473
474 if (VT.isVector())
475 return false;
476
477 return VT.getScalarSizeInBits() <= 32;
478 }
479
480 bool shouldFoldSelectWithIdentityConstant(unsigned BinOpcode, EVT VT,
481 unsigned SelectOpcode, SDValue X,
482 SDValue Y) const override;
483
484 bool preferIncOfAddToSubOfNot(EVT VT) const override;
485
486 bool shouldConvertFpToSat(unsigned Op, EVT FPVT, EVT VT) const override;
487
488 bool isComplexDeinterleavingSupported() const override;
489 bool isComplexDeinterleavingOperationSupported(
490 ComplexDeinterleavingOperation Operation, Type *Ty) const override;
491
492 Value *createComplexDeinterleavingIR(
493 IRBuilderBase &B, ComplexDeinterleavingOperation OperationType,
494 ComplexDeinterleavingRotation Rotation, Value *InputA, Value *InputB,
495 Value *Accumulator = nullptr) const override;
496
497 bool useFPRegsForHalfType() const override { return true; }
498
499 protected:
500 std::pair<const TargetRegisterClass *, uint8_t>
501 findRepresentativeClass(const TargetRegisterInfo *TRI,
502 MVT VT) const override;
503
504 private:
505 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
506 /// make the right decision when generating code for different targets.
507 const ARMSubtarget *Subtarget;
508
509 const TargetRegisterInfo *RegInfo;
510
511 const InstrItineraryData *Itins;
512
513 // TODO: remove this, and have shouldInsertFencesForAtomic do the proper
514 // check.
515 bool InsertFencesForAtomic;
516
517 bool HasStandaloneRem = true;
518
519 void addTypeForNEON(MVT VT, MVT PromotedLdStVT);
520 void addDRTypeForNEON(MVT VT);
521 void addQRTypeForNEON(MVT VT);
522 std::pair<SDValue, SDValue> getARMXALUOOp(SDValue Op, SelectionDAG &DAG, SDValue &ARMcc) const;
523
524 using RegsToPassVector = SmallVector<std::pair<unsigned, SDValue>, 8>;
525
526 void PassF64ArgInRegs(const SDLoc &dl, SelectionDAG &DAG, SDValue Chain,
527 SDValue &Arg, RegsToPassVector &RegsToPass,
528 CCValAssign &VA, CCValAssign &NextVA,
529 SDValue &StackPtr,
530 SmallVectorImpl<SDValue> &MemOpChains,
531 bool IsTailCall,
532 int SPDiff) const;
533 SDValue GetF64FormalArgument(CCValAssign &VA, CCValAssign &NextVA,
534 SDValue &Root, SelectionDAG &DAG,
535 const SDLoc &dl) const;
536
537 CallingConv::ID getEffectiveCallingConv(CallingConv::ID CC,
538 bool isVarArg) const;
539 CCAssignFn *CCAssignFnForNode(CallingConv::ID CC, bool Return,
540 bool isVarArg) const;
541 std::pair<SDValue, MachinePointerInfo>
542 computeAddrForCallArg(const SDLoc &dl, SelectionDAG &DAG,
543 const CCValAssign &VA, SDValue StackPtr,
544 bool IsTailCall, int SPDiff) const;
545 ByValCopyKind ByValNeedsCopyForTailCall(SelectionDAG &DAG, SDValue Src,
546 SDValue Dst,
547 ISD::ArgFlagsTy Flags) const;
548 SDValue LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;
549 SDValue LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;
550 SDValue LowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const;
551 SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG,
552 const ARMSubtarget *Subtarget) const;
553 SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
554 const ARMSubtarget *Subtarget) const;
555 SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
556 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
557 SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
558 SDValue LowerGlobalAddressDarwin(SDValue Op, SelectionDAG &DAG) const;
559 SDValue LowerGlobalAddressELF(SDValue Op, SelectionDAG &DAG) const;
560 SDValue LowerGlobalAddressWindows(SDValue Op, SelectionDAG &DAG) const;
561 SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
562 SDValue LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
563 SelectionDAG &DAG) const;
564 SDValue LowerToTLSExecModels(GlobalAddressSDNode *GA,
565 SelectionDAG &DAG,
566 TLSModel::Model model) const;
567 SDValue LowerGlobalTLSAddressDarwin(SDValue Op, SelectionDAG &DAG) const;
568 SDValue LowerGlobalTLSAddressWindows(SDValue Op, SelectionDAG &DAG) const;
569 SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const;
570 SDValue LowerSignedALUO(SDValue Op, SelectionDAG &DAG) const;
571 SDValue LowerUnsignedALUO(SDValue Op, SelectionDAG &DAG) const;
572 SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const;
573 SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
574 SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
575 SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
576 SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const;
577 SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
578 SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
579 SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG) const;
580 SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;
581 SDValue LowerGET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;
582 SDValue LowerSET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;
583 SDValue LowerSET_FPMODE(SDValue Op, SelectionDAG &DAG) const;
584 SDValue LowerRESET_FPMODE(SDValue Op, SelectionDAG &DAG) const;
585 SDValue LowerConstantFP(SDValue Op, SelectionDAG &DAG,
586 const ARMSubtarget *ST) const;
587 SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
588 const ARMSubtarget *ST) const;
589 SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
590 SDValue LowerDivRem(SDValue Op, SelectionDAG &DAG) const;
591 SDValue LowerDIV_Windows(SDValue Op, SelectionDAG &DAG, bool Signed) const;
592 void ExpandDIV_Windows(SDValue Op, SelectionDAG &DAG, bool Signed,
593 SmallVectorImpl<SDValue> &Results) const;
594 SDValue ExpandBITCAST(SDNode *N, SelectionDAG &DAG,
595 const ARMSubtarget *Subtarget) const;
596 SDValue LowerWindowsDIVLibCall(SDValue Op, SelectionDAG &DAG, bool Signed,
597 SDValue &Chain) const;
598 SDValue LowerREM(SDNode *N, SelectionDAG &DAG) const;
599 SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
600 SDValue LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const;
601 SDValue LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const;
602 SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const;
603 SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
604 SDValue LowerFSETCC(SDValue Op, SelectionDAG &DAG) const;
605 SDValue LowerSPONENTRY(SDValue Op, SelectionDAG &DAG) const;
606 void LowerLOAD(SDNode *N, SmallVectorImpl<SDValue> &Results,
607 SelectionDAG &DAG) const;
608 SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG,
609 const ARMSubtarget *Subtarget) const;
610 std::pair<SDValue, SDValue>
611 LowerAEABIUnalignedLoad(SDValue Op, SelectionDAG &DAG) const;
612 SDValue LowerAEABIUnalignedStore(SDValue Op, SelectionDAG &DAG) const;
613 SDValue LowerFP_TO_BF16(SDValue Op, SelectionDAG &DAG) const;
614 SDValue LowerCMP(SDValue Op, SelectionDAG &DAG) const;
615 SDValue LowerABS(SDValue Op, SelectionDAG &DAG) const;
616 Register getRegisterByName(const char* RegName, LLT VT,
617 const MachineFunction &MF) const override;
618
619 SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG,
620 SmallVectorImpl<SDNode *> &Created) const override;
621
622 bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
623 EVT VT) const override;
624
625 SDValue MoveToHPR(const SDLoc &dl, SelectionDAG &DAG, MVT LocVT, MVT ValVT,
626 SDValue Val) const;
627 SDValue MoveFromHPR(const SDLoc &dl, SelectionDAG &DAG, MVT LocVT,
628 MVT ValVT, SDValue Val) const;
629
630 SDValue ReconstructShuffle(SDValue Op, SelectionDAG &DAG) const;
631
632 SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
633 CallingConv::ID CallConv, bool isVarArg,
634 const SmallVectorImpl<ISD::InputArg> &Ins,
635 const SDLoc &dl, SelectionDAG &DAG,
636 SmallVectorImpl<SDValue> &InVals, bool isThisReturn,
637 SDValue ThisVal, bool isCmseNSCall) const;
638
639 void initializeSplitCSR(MachineBasicBlock *Entry) const override;
640 void insertCopiesSplitCSR(
641 MachineBasicBlock *Entry,
642 const SmallVectorImpl<MachineBasicBlock *> &Exits) const override;
643
644 bool splitValueIntoRegisterParts(
645 SelectionDAG & DAG, const SDLoc &DL, SDValue Val, SDValue *Parts,
646 unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC)
647 const override;
648
649 SDValue joinRegisterPartsIntoValue(
650 SelectionDAG & DAG, const SDLoc &DL, const SDValue *Parts,
651 unsigned NumParts, MVT PartVT, EVT ValueVT,
652 std::optional<CallingConv::ID> CC) const override;
653
654 SDValue
655 LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
656 const SmallVectorImpl<ISD::InputArg> &Ins,
657 const SDLoc &dl, SelectionDAG &DAG,
658 SmallVectorImpl<SDValue> &InVals) const override;
659
660 int StoreByValRegs(CCState &CCInfo, SelectionDAG &DAG, const SDLoc &dl,
661 SDValue &Chain, const Value *OrigArg,
662 unsigned InRegsParamRecordIdx, int ArgOffset,
663 unsigned ArgSize) const;
664
665 void VarArgStyleRegisters(CCState &CCInfo, SelectionDAG &DAG,
666 const SDLoc &dl, SDValue &Chain,
667 unsigned ArgOffset, unsigned TotalArgRegsSaveSize,
668 bool ForceMutable = false) const;
669
670 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
671 SmallVectorImpl<SDValue> &InVals) const override;
672
673 /// HandleByVal - Target-specific cleanup for ByVal support.
674 void HandleByVal(CCState *, unsigned &, Align) const override;
675
676 /// IsEligibleForTailCallOptimization - Check whether the call is eligible
677 /// for tail call optimization. Targets which want to do tail call
678 /// optimization should implement this function.
679 bool IsEligibleForTailCallOptimization(
680 TargetLowering::CallLoweringInfo &CLI, CCState &CCInfo,
681 SmallVectorImpl<CCValAssign> &ArgLocs, const bool isIndirect) const;
682
683 bool CanLowerReturn(CallingConv::ID CallConv,
684 MachineFunction &MF, bool isVarArg,
685 const SmallVectorImpl<ISD::OutputArg> &Outs,
686 LLVMContext &Context, const Type *RetTy) const override;
687
688 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
689 const SmallVectorImpl<ISD::OutputArg> &Outs,
690 const SmallVectorImpl<SDValue> &OutVals,
691 const SDLoc &dl, SelectionDAG &DAG) const override;
692
693 bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override;
694
695 bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
696
697 bool shouldConsiderGEPOffsetSplit() const override { return true; }
698
699 bool isUnsupportedFloatingType(EVT VT) const;
700
701 ArrayRef<MCPhysReg> getRoundingControlRegisters() const override;
702
703 SDValue getCMOV(const SDLoc &dl, EVT VT, SDValue FalseVal, SDValue TrueVal,
704 SDValue ARMcc, SDValue Flags, SelectionDAG &DAG) const;
705 SDValue getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
706 SDValue &ARMcc, SelectionDAG &DAG, const SDLoc &dl) const;
707 SDValue getVFPCmp(SDValue LHS, SDValue RHS, SelectionDAG &DAG,
708 const SDLoc &dl, bool Signaling = false) const;
709
710 SDValue OptimizeVFPBrcond(SDValue Op, SelectionDAG &DAG) const;
711
712 void SetupEntryBlockForSjLj(MachineInstr &MI, MachineBasicBlock *MBB,
713 MachineBasicBlock *DispatchBB, int FI) const;
714
715 void EmitSjLjDispatchBlock(MachineInstr &MI, MachineBasicBlock *MBB) const;
716
717 MachineBasicBlock *EmitStructByval(MachineInstr &MI,
718 MachineBasicBlock *MBB) const;
719
720 MachineBasicBlock *EmitLowered__chkstk(MachineInstr &MI,
721 MachineBasicBlock *MBB) const;
722 MachineBasicBlock *EmitLowered__dbzchk(MachineInstr &MI,
723 MachineBasicBlock *MBB) const;
724 void addMVEVectorTypes(bool HasMVEFP);
725 void addAllExtLoads(const MVT From, const MVT To, LegalizeAction Action);
726 void setAllExpand(MVT VT);
727 };
728
729 enum VMOVModImmType {
730 VMOVModImm,
731 VMVNModImm,
732 MVEVMVNModImm,
733 OtherModImm
734 };
735
736 namespace ARM {
737
738 FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
739 const TargetLibraryInfo *libInfo,
740 const LibcallLoweringInfo *libcallLowering);
741
742 } // end namespace ARM
743
744} // end namespace llvm
745
746#endif // LLVM_LIB_TARGET_ARM_ARMISELLOWERING_H
747