1 //==-- AArch64ISelLowering.h - AArch64 DAG Lowering Interface ----*- C++ -*-==//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines the interfaces that AArch64 uses to lower LLVM code into a
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64ISELLOWERING_H
15 #define LLVM_LIB_TARGET_AARCH64_AARCH64ISELLOWERING_H
18 #include "llvm/CodeGen/CallingConvLower.h"
19 #include "llvm/CodeGen/SelectionDAG.h"
20 #include "llvm/CodeGen/TargetLowering.h"
21 #include "llvm/IR/CallingConv.h"
22 #include "llvm/IR/Instruction.h"
26 namespace AArch64ISD
{
28 enum NodeType
: unsigned {
29 FIRST_NUMBER
= ISD::BUILTIN_OP_END
,
30 WrapperLarge
, // 4-instruction MOVZ/MOVK sequence for 64-bit addresses.
31 CALL
, // Function call.
33 // Produces the full sequence of instructions for getting the thread pointer
34 // offset of a variable into X0, using the TLSDesc model.
36 ADRP
, // Page address of a TargetGlobalAddress operand.
38 ADDlow
, // Add the low 12 bits of a TargetGlobalAddress operand.
39 LOADgot
, // Load from automatically generated descriptor (e.g. Global
40 // Offset Table, TLS record).
41 RET_FLAG
, // Return with a flag operand. Operand 0 is the chain operand.
42 BRCOND
, // Conditional branch instruction; "b.cond".
44 FCSEL
, // Conditional move instruction.
45 CSINV
, // Conditional select invert.
46 CSNEG
, // Conditional select negate.
47 CSINC
, // Conditional select increment.
49 // Pointer to the thread's local storage area. Materialised from TPIDR_EL0 on
53 SBC
, // adc, sbc instructions
55 // Arithmetic instructions which write flags.
62 // Conditional compares. Operands: left,right,falsecc,cc,flags
67 // Floating point comparison
73 // Scalar-to-vector duplication
80 // Vector immedate moves
89 // Vector immediate ops
93 // Vector bit select: similar to ISD::VSELECT but not all bits within an
94 // element must be identical.
97 // Vector arithmetic negation
112 // Vector shift by scalar
117 // Vector shift by scalar (again)
124 // Vector comparisons
134 // Vector zero comparisons
146 // Vector across-lanes addition
147 // Only the lower result lane is defined.
151 // Vector across-lanes min/max
152 // Only the lower result lane is defined.
158 // Vector bitwise negation
161 // Vector bitwise selection
164 // Compare-and-branch
173 // Custom prefetch handling
176 // {s|u}int to FP within a FP register.
180 /// Natural vector cast. ISD::BITCAST is not natural in the big-endian
181 /// world w.r.t vectors; which causes additional REV instructions to be
182 /// generated to compensate for the byte-swapping. But sometimes we do
183 /// need to re-interpret the data in SIMD vector registers in big-endian
184 /// mode without emitting such REV instructions.
190 // Reciprocal estimates and steps.
194 // NEON Load/Store with post-increment base updates
195 LD2post
= ISD::FIRST_TARGET_MEMORY_OPCODE
,
220 } // end namespace AArch64ISD
224 // Any instruction that defines a 32-bit result zeros out the high half of the
225 // register. Truncate can be lowered to EXTRACT_SUBREG. CopyFromReg may
226 // be copying from a truncate. But any other 32-bit operation will zero-extend
228 // FIXME: X86 also checks for CMOV here. Do we need something similar?
229 static inline bool isDef32(const SDNode
&N
) {
230 unsigned Opc
= N
.getOpcode();
231 return Opc
!= ISD::TRUNCATE
&& Opc
!= TargetOpcode::EXTRACT_SUBREG
&&
232 Opc
!= ISD::CopyFromReg
;
235 } // end anonymous namespace
237 class AArch64Subtarget
;
238 class AArch64TargetMachine
;
240 class AArch64TargetLowering
: public TargetLowering
{
242 explicit AArch64TargetLowering(const TargetMachine
&TM
,
243 const AArch64Subtarget
&STI
);
245 /// Selects the correct CCAssignFn for a given CallingConvention value.
246 CCAssignFn
*CCAssignFnForCall(CallingConv::ID CC
, bool IsVarArg
) const;
248 /// Selects the correct CCAssignFn for a given CallingConvention value.
249 CCAssignFn
*CCAssignFnForReturn(CallingConv::ID CC
) const;
251 /// Determine which of the bits specified in Mask are known to be either zero
252 /// or one and return them in the KnownZero/KnownOne bitsets.
253 void computeKnownBitsForTargetNode(const SDValue Op
, KnownBits
&Known
,
254 const APInt
&DemandedElts
,
255 const SelectionDAG
&DAG
,
256 unsigned Depth
= 0) const override
;
258 bool targetShrinkDemandedConstant(SDValue Op
, const APInt
&Demanded
,
259 TargetLoweringOpt
&TLO
) const override
;
261 MVT
getScalarShiftAmountTy(const DataLayout
&DL
, EVT
) const override
;
263 /// Returns true if the target allows unaligned memory accesses of the
265 bool allowsMisalignedMemoryAccesses(EVT VT
, unsigned AddrSpace
= 0,
267 bool *Fast
= nullptr) const override
;
269 /// Provide custom lowering hooks for some operations.
270 SDValue
LowerOperation(SDValue Op
, SelectionDAG
&DAG
) const override
;
272 const char *getTargetNodeName(unsigned Opcode
) const override
;
274 SDValue
PerformDAGCombine(SDNode
*N
, DAGCombinerInfo
&DCI
) const override
;
276 /// Returns true if a cast between SrcAS and DestAS is a noop.
277 bool isNoopAddrSpaceCast(unsigned SrcAS
, unsigned DestAS
) const override
{
278 // Addrspacecasts are always noops.
282 /// This method returns a target specific FastISel object, or null if the
283 /// target does not support "fast" ISel.
284 FastISel
*createFastISel(FunctionLoweringInfo
&funcInfo
,
285 const TargetLibraryInfo
*libInfo
) const override
;
287 bool isOffsetFoldingLegal(const GlobalAddressSDNode
*GA
) const override
;
289 bool isFPImmLegal(const APFloat
&Imm
, EVT VT
) const override
;
291 /// Return true if the given shuffle mask can be codegen'd directly, or if it
292 /// should be stack expanded.
293 bool isShuffleMaskLegal(ArrayRef
<int> M
, EVT VT
) const override
;
295 /// Return the ISD::SETCC ValueType.
296 EVT
getSetCCResultType(const DataLayout
&DL
, LLVMContext
&Context
,
297 EVT VT
) const override
;
299 SDValue
ReconstructShuffle(SDValue Op
, SelectionDAG
&DAG
) const;
301 MachineBasicBlock
*EmitF128CSEL(MachineInstr
&MI
,
302 MachineBasicBlock
*BB
) const;
304 MachineBasicBlock
*EmitLoweredCatchRet(MachineInstr
&MI
,
305 MachineBasicBlock
*BB
) const;
307 MachineBasicBlock
*EmitLoweredCatchPad(MachineInstr
&MI
,
308 MachineBasicBlock
*BB
) const;
311 EmitInstrWithCustomInserter(MachineInstr
&MI
,
312 MachineBasicBlock
*MBB
) const override
;
314 bool getTgtMemIntrinsic(IntrinsicInfo
&Info
, const CallInst
&I
,
316 unsigned Intrinsic
) const override
;
318 bool shouldReduceLoadWidth(SDNode
*Load
, ISD::LoadExtType ExtTy
,
319 EVT NewVT
) const override
;
321 bool isTruncateFree(Type
*Ty1
, Type
*Ty2
) const override
;
322 bool isTruncateFree(EVT VT1
, EVT VT2
) const override
;
324 bool isProfitableToHoist(Instruction
*I
) const override
;
326 bool isZExtFree(Type
*Ty1
, Type
*Ty2
) const override
;
327 bool isZExtFree(EVT VT1
, EVT VT2
) const override
;
328 bool isZExtFree(SDValue Val
, EVT VT2
) const override
;
330 bool shouldSinkOperands(Instruction
*I
,
331 SmallVectorImpl
<Use
*> &Ops
) const override
;
333 bool hasPairedLoad(EVT LoadedType
, unsigned &RequiredAligment
) const override
;
335 unsigned getMaxSupportedInterleaveFactor() const override
{ return 4; }
337 bool lowerInterleavedLoad(LoadInst
*LI
,
338 ArrayRef
<ShuffleVectorInst
*> Shuffles
,
339 ArrayRef
<unsigned> Indices
,
340 unsigned Factor
) const override
;
341 bool lowerInterleavedStore(StoreInst
*SI
, ShuffleVectorInst
*SVI
,
342 unsigned Factor
) const override
;
344 bool isLegalAddImmediate(int64_t) const override
;
345 bool isLegalICmpImmediate(int64_t) const override
;
347 bool shouldConsiderGEPOffsetSplit() const override
;
349 EVT
getOptimalMemOpType(uint64_t Size
, unsigned DstAlign
, unsigned SrcAlign
,
350 bool IsMemset
, bool ZeroMemset
, bool MemcpyStrSrc
,
351 MachineFunction
&MF
) const override
;
353 /// Return true if the addressing mode represented by AM is legal for this
354 /// target, for a load/store of the specified type.
355 bool isLegalAddressingMode(const DataLayout
&DL
, const AddrMode
&AM
, Type
*Ty
,
357 Instruction
*I
= nullptr) const override
;
359 /// Return the cost of the scaling factor used in the addressing
360 /// mode represented by AM for this target, for a load/store
361 /// of the specified type.
362 /// If the AM is supported, the return value must be >= 0.
363 /// If the AM is not supported, it returns a negative value.
364 int getScalingFactorCost(const DataLayout
&DL
, const AddrMode
&AM
, Type
*Ty
,
365 unsigned AS
) const override
;
367 /// Return true if an FMA operation is faster than a pair of fmul and fadd
368 /// instructions. fmuladd intrinsics will be expanded to FMAs when this method
369 /// returns true, otherwise fmuladd is expanded to fmul + fadd.
370 bool isFMAFasterThanFMulAndFAdd(EVT VT
) const override
;
372 const MCPhysReg
*getScratchRegisters(CallingConv::ID CC
) const override
;
374 /// Returns false if N is a bit extraction pattern of (X >> C) & Mask.
375 bool isDesirableToCommuteWithShift(const SDNode
*N
,
376 CombineLevel Level
) const override
;
378 /// Returns true if it is beneficial to convert a load of a constant
379 /// to just the constant itself.
380 bool shouldConvertConstantLoadToIntImm(const APInt
&Imm
,
381 Type
*Ty
) const override
;
383 /// Return true if EXTRACT_SUBVECTOR is cheap for this result type
385 bool isExtractSubvectorCheap(EVT ResVT
, EVT SrcVT
,
386 unsigned Index
) const override
;
388 Value
*emitLoadLinked(IRBuilder
<> &Builder
, Value
*Addr
,
389 AtomicOrdering Ord
) const override
;
390 Value
*emitStoreConditional(IRBuilder
<> &Builder
, Value
*Val
,
391 Value
*Addr
, AtomicOrdering Ord
) const override
;
393 void emitAtomicCmpXchgNoStoreLLBalance(IRBuilder
<> &Builder
) const override
;
395 TargetLoweringBase::AtomicExpansionKind
396 shouldExpandAtomicLoadInIR(LoadInst
*LI
) const override
;
397 bool shouldExpandAtomicStoreInIR(StoreInst
*SI
) const override
;
398 TargetLoweringBase::AtomicExpansionKind
399 shouldExpandAtomicRMWInIR(AtomicRMWInst
*AI
) const override
;
401 TargetLoweringBase::AtomicExpansionKind
402 shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst
*AI
) const override
;
404 bool useLoadStackGuardNode() const override
;
405 TargetLoweringBase::LegalizeTypeAction
406 getPreferredVectorAction(MVT VT
) const override
;
408 /// If the target has a standard location for the stack protector cookie,
409 /// returns the address of that location. Otherwise, returns nullptr.
410 Value
*getIRStackGuard(IRBuilder
<> &IRB
) const override
;
412 void insertSSPDeclarations(Module
&M
) const override
;
413 Value
*getSDagStackGuard(const Module
&M
) const override
;
414 Function
*getSSPStackGuardCheck(const Module
&M
) const override
;
416 /// If the target has a standard location for the unsafe stack pointer,
417 /// returns the address of that location. Otherwise, returns nullptr.
418 Value
*getSafeStackPointerLocation(IRBuilder
<> &IRB
) const override
;
420 /// If a physical register, this returns the register that receives the
421 /// exception address on entry to an EH pad.
423 getExceptionPointerRegister(const Constant
*PersonalityFn
) const override
{
424 // FIXME: This is a guess. Has this been defined yet?
428 /// If a physical register, this returns the register that receives the
429 /// exception typeid on entry to a landing pad.
431 getExceptionSelectorRegister(const Constant
*PersonalityFn
) const override
{
432 // FIXME: This is a guess. Has this been defined yet?
436 bool isIntDivCheap(EVT VT
, AttributeList Attr
) const override
;
438 bool canMergeStoresTo(unsigned AddressSpace
, EVT MemVT
,
439 const SelectionDAG
&DAG
) const override
{
440 // Do not merge to float value size (128 bytes) if no implicit
441 // float attribute is set.
443 bool NoFloat
= DAG
.getMachineFunction().getFunction().hasFnAttribute(
444 Attribute::NoImplicitFloat
);
447 return (MemVT
.getSizeInBits() <= 64);
451 bool isCheapToSpeculateCttz() const override
{
455 bool isCheapToSpeculateCtlz() const override
{
459 bool isMaskAndCmp0FoldingBeneficial(const Instruction
&AndI
) const override
;
461 bool hasAndNotCompare(SDValue V
) const override
{
462 // We can use bics for any scalar.
463 return V
.getValueType().isScalarInteger();
466 bool hasAndNot(SDValue Y
) const override
{
467 EVT VT
= Y
.getValueType();
470 return hasAndNotCompare(Y
);
472 return VT
.getSizeInBits() >= 64; // vector 'bic'
475 bool shouldExpandShift(SelectionDAG
&DAG
, SDNode
*N
) const override
{
476 if (DAG
.getMachineFunction().getFunction().optForMinSize())
481 bool shouldTransformSignedTruncationCheck(EVT XVT
,
482 unsigned KeptBits
) const override
{
483 // For vectors, we don't have a preference..
487 auto VTIsOk
= [](EVT VT
) -> bool {
488 return VT
== MVT::i8
|| VT
== MVT::i16
|| VT
== MVT::i32
||
492 // We are ok with KeptBitsVT being byte/word/dword, what SXT supports.
493 // XVT will be larger than KeptBitsVT.
494 MVT KeptBitsVT
= MVT::getIntegerVT(KeptBits
);
495 return VTIsOk(XVT
) && VTIsOk(KeptBitsVT
);
498 bool hasBitPreservingFPLogic(EVT VT
) const override
{
499 // FIXME: Is this always true? It should be true for vectors at least.
500 return VT
== MVT::f32
|| VT
== MVT::f64
;
503 bool supportSplitCSR(MachineFunction
*MF
) const override
{
504 return MF
->getFunction().getCallingConv() == CallingConv::CXX_FAST_TLS
&&
505 MF
->getFunction().hasFnAttribute(Attribute::NoUnwind
);
507 void initializeSplitCSR(MachineBasicBlock
*Entry
) const override
;
508 void insertCopiesSplitCSR(
509 MachineBasicBlock
*Entry
,
510 const SmallVectorImpl
<MachineBasicBlock
*> &Exits
) const override
;
512 bool supportSwiftError() const override
{
516 /// Enable aggressive FMA fusion on targets that want it.
517 bool enableAggressiveFMAFusion(EVT VT
) const override
;
519 /// Returns the size of the platform's va_list object.
520 unsigned getVaListSizeInBits(const DataLayout
&DL
) const override
;
522 /// Returns true if \p VecTy is a legal interleaved access type. This
523 /// function checks the vector element type and the overall width of the
525 bool isLegalInterleavedAccessType(VectorType
*VecTy
,
526 const DataLayout
&DL
) const;
528 /// Returns the number of interleaved accesses that will be generated when
529 /// lowering accesses of the given type.
530 unsigned getNumInterleavedAccesses(VectorType
*VecTy
,
531 const DataLayout
&DL
) const;
533 MachineMemOperand::Flags
getMMOFlags(const Instruction
&I
) const override
;
535 bool functionArgumentNeedsConsecutiveRegisters(Type
*Ty
,
536 CallingConv::ID CallConv
,
537 bool isVarArg
) const override
;
538 /// Used for exception handling on Win64.
539 bool needsFixedCatchObjects() const override
;
541 /// Keep a pointer to the AArch64Subtarget around so that we can
542 /// make the right decision when generating code for different targets.
543 const AArch64Subtarget
*Subtarget
;
545 bool isExtFreeImpl(const Instruction
*Ext
) const override
;
547 void addTypeForNEON(MVT VT
, MVT PromotedBitwiseVT
);
548 void addDRTypeForNEON(MVT VT
);
549 void addQRTypeForNEON(MVT VT
);
551 SDValue
LowerFormalArguments(SDValue Chain
, CallingConv::ID CallConv
,
553 const SmallVectorImpl
<ISD::InputArg
> &Ins
,
554 const SDLoc
&DL
, SelectionDAG
&DAG
,
555 SmallVectorImpl
<SDValue
> &InVals
) const override
;
557 SDValue
LowerCall(CallLoweringInfo
& /*CLI*/,
558 SmallVectorImpl
<SDValue
> &InVals
) const override
;
560 SDValue
LowerCallResult(SDValue Chain
, SDValue InFlag
,
561 CallingConv::ID CallConv
, bool isVarArg
,
562 const SmallVectorImpl
<ISD::InputArg
> &Ins
,
563 const SDLoc
&DL
, SelectionDAG
&DAG
,
564 SmallVectorImpl
<SDValue
> &InVals
, bool isThisReturn
,
565 SDValue ThisVal
) const;
567 SDValue
LowerSTORE(SDValue Op
, SelectionDAG
&DAG
) const;
569 SDValue
LowerINTRINSIC_WO_CHAIN(SDValue Op
, SelectionDAG
&DAG
) const;
571 bool isEligibleForTailCallOptimization(
572 SDValue Callee
, CallingConv::ID CalleeCC
, bool isVarArg
,
573 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
574 const SmallVectorImpl
<SDValue
> &OutVals
,
575 const SmallVectorImpl
<ISD::InputArg
> &Ins
, SelectionDAG
&DAG
) const;
577 /// Finds the incoming stack arguments which overlap the given fixed stack
578 /// object and incorporates their load into the current chain. This prevents
579 /// an upcoming store from clobbering the stack argument before it's used.
580 SDValue
addTokenForArgument(SDValue Chain
, SelectionDAG
&DAG
,
581 MachineFrameInfo
&MFI
, int ClobberedFI
) const;
583 bool DoesCalleeRestoreStack(CallingConv::ID CallCC
, bool TailCallOpt
) const;
585 void saveVarArgRegisters(CCState
&CCInfo
, SelectionDAG
&DAG
, const SDLoc
&DL
,
586 SDValue
&Chain
) const;
588 bool CanLowerReturn(CallingConv::ID CallConv
, MachineFunction
&MF
,
590 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
591 LLVMContext
&Context
) const override
;
593 SDValue
LowerReturn(SDValue Chain
, CallingConv::ID CallConv
, bool isVarArg
,
594 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
595 const SmallVectorImpl
<SDValue
> &OutVals
, const SDLoc
&DL
,
596 SelectionDAG
&DAG
) const override
;
598 SDValue
getTargetNode(GlobalAddressSDNode
*N
, EVT Ty
, SelectionDAG
&DAG
,
599 unsigned Flag
) const;
600 SDValue
getTargetNode(JumpTableSDNode
*N
, EVT Ty
, SelectionDAG
&DAG
,
601 unsigned Flag
) const;
602 SDValue
getTargetNode(ConstantPoolSDNode
*N
, EVT Ty
, SelectionDAG
&DAG
,
603 unsigned Flag
) const;
604 SDValue
getTargetNode(BlockAddressSDNode
*N
, EVT Ty
, SelectionDAG
&DAG
,
605 unsigned Flag
) const;
606 template <class NodeTy
>
607 SDValue
getGOT(NodeTy
*N
, SelectionDAG
&DAG
, unsigned Flags
= 0) const;
608 template <class NodeTy
>
609 SDValue
getAddrLarge(NodeTy
*N
, SelectionDAG
&DAG
, unsigned Flags
= 0) const;
610 template <class NodeTy
>
611 SDValue
getAddr(NodeTy
*N
, SelectionDAG
&DAG
, unsigned Flags
= 0) const;
612 template <class NodeTy
>
613 SDValue
getAddrTiny(NodeTy
*N
, SelectionDAG
&DAG
, unsigned Flags
= 0) const;
614 SDValue
LowerADDROFRETURNADDR(SDValue Op
, SelectionDAG
&DAG
) const;
615 SDValue
LowerGlobalAddress(SDValue Op
, SelectionDAG
&DAG
) const;
616 SDValue
LowerGlobalTLSAddress(SDValue Op
, SelectionDAG
&DAG
) const;
617 SDValue
LowerDarwinGlobalTLSAddress(SDValue Op
, SelectionDAG
&DAG
) const;
618 SDValue
LowerELFGlobalTLSAddress(SDValue Op
, SelectionDAG
&DAG
) const;
619 SDValue
LowerELFTLSDescCallSeq(SDValue SymAddr
, const SDLoc
&DL
,
620 SelectionDAG
&DAG
) const;
621 SDValue
LowerWindowsGlobalTLSAddress(SDValue Op
, SelectionDAG
&DAG
) const;
622 SDValue
LowerSETCC(SDValue Op
, SelectionDAG
&DAG
) const;
623 SDValue
LowerBR_CC(SDValue Op
, SelectionDAG
&DAG
) const;
624 SDValue
LowerSELECT(SDValue Op
, SelectionDAG
&DAG
) const;
625 SDValue
LowerSELECT_CC(SDValue Op
, SelectionDAG
&DAG
) const;
626 SDValue
LowerSELECT_CC(ISD::CondCode CC
, SDValue LHS
, SDValue RHS
,
627 SDValue TVal
, SDValue FVal
, const SDLoc
&dl
,
628 SelectionDAG
&DAG
) const;
629 SDValue
LowerJumpTable(SDValue Op
, SelectionDAG
&DAG
) const;
630 SDValue
LowerBR_JT(SDValue Op
, SelectionDAG
&DAG
) const;
631 SDValue
LowerConstantPool(SDValue Op
, SelectionDAG
&DAG
) const;
632 SDValue
LowerBlockAddress(SDValue Op
, SelectionDAG
&DAG
) const;
633 SDValue
LowerAAPCS_VASTART(SDValue Op
, SelectionDAG
&DAG
) const;
634 SDValue
LowerDarwin_VASTART(SDValue Op
, SelectionDAG
&DAG
) const;
635 SDValue
LowerWin64_VASTART(SDValue Op
, SelectionDAG
&DAG
) const;
636 SDValue
LowerVASTART(SDValue Op
, SelectionDAG
&DAG
) const;
637 SDValue
LowerVACOPY(SDValue Op
, SelectionDAG
&DAG
) const;
638 SDValue
LowerVAARG(SDValue Op
, SelectionDAG
&DAG
) const;
639 SDValue
LowerFRAMEADDR(SDValue Op
, SelectionDAG
&DAG
) const;
640 SDValue
LowerSPONENTRY(SDValue Op
, SelectionDAG
&DAG
) const;
641 SDValue
LowerRETURNADDR(SDValue Op
, SelectionDAG
&DAG
) const;
642 SDValue
LowerFLT_ROUNDS_(SDValue Op
, SelectionDAG
&DAG
) const;
643 SDValue
LowerINSERT_VECTOR_ELT(SDValue Op
, SelectionDAG
&DAG
) const;
644 SDValue
LowerEXTRACT_VECTOR_ELT(SDValue Op
, SelectionDAG
&DAG
) const;
645 SDValue
LowerSCALAR_TO_VECTOR(SDValue Op
, SelectionDAG
&DAG
) const;
646 SDValue
LowerBUILD_VECTOR(SDValue Op
, SelectionDAG
&DAG
) const;
647 SDValue
LowerVECTOR_SHUFFLE(SDValue Op
, SelectionDAG
&DAG
) const;
648 SDValue
LowerEXTRACT_SUBVECTOR(SDValue Op
, SelectionDAG
&DAG
) const;
649 SDValue
LowerVectorSRA_SRL_SHL(SDValue Op
, SelectionDAG
&DAG
) const;
650 SDValue
LowerShiftLeftParts(SDValue Op
, SelectionDAG
&DAG
) const;
651 SDValue
LowerShiftRightParts(SDValue Op
, SelectionDAG
&DAG
) const;
652 SDValue
LowerVSETCC(SDValue Op
, SelectionDAG
&DAG
) const;
653 SDValue
LowerCTPOP(SDValue Op
, SelectionDAG
&DAG
) const;
654 SDValue
LowerF128Call(SDValue Op
, SelectionDAG
&DAG
,
655 RTLIB::Libcall Call
) const;
656 SDValue
LowerFCOPYSIGN(SDValue Op
, SelectionDAG
&DAG
) const;
657 SDValue
LowerFP_EXTEND(SDValue Op
, SelectionDAG
&DAG
) const;
658 SDValue
LowerFP_ROUND(SDValue Op
, SelectionDAG
&DAG
) const;
659 SDValue
LowerFP_TO_INT(SDValue Op
, SelectionDAG
&DAG
) const;
660 SDValue
LowerINT_TO_FP(SDValue Op
, SelectionDAG
&DAG
) const;
661 SDValue
LowerVectorAND(SDValue Op
, SelectionDAG
&DAG
) const;
662 SDValue
LowerVectorOR(SDValue Op
, SelectionDAG
&DAG
) const;
663 SDValue
LowerCONCAT_VECTORS(SDValue Op
, SelectionDAG
&DAG
) const;
664 SDValue
LowerFSINCOS(SDValue Op
, SelectionDAG
&DAG
) const;
665 SDValue
LowerVECREDUCE(SDValue Op
, SelectionDAG
&DAG
) const;
666 SDValue
LowerATOMIC_LOAD_SUB(SDValue Op
, SelectionDAG
&DAG
) const;
667 SDValue
LowerATOMIC_LOAD_AND(SDValue Op
, SelectionDAG
&DAG
) const;
668 SDValue
LowerDYNAMIC_STACKALLOC(SDValue Op
, SelectionDAG
&DAG
) const;
669 SDValue
LowerWindowsDYNAMIC_STACKALLOC(SDValue Op
, SDValue Chain
,
671 SelectionDAG
&DAG
) const;
673 SDValue
BuildSDIVPow2(SDNode
*N
, const APInt
&Divisor
, SelectionDAG
&DAG
,
674 SmallVectorImpl
<SDNode
*> &Created
) const override
;
675 SDValue
getSqrtEstimate(SDValue Operand
, SelectionDAG
&DAG
, int Enabled
,
676 int &ExtraSteps
, bool &UseOneConst
,
677 bool Reciprocal
) const override
;
678 SDValue
getRecipEstimate(SDValue Operand
, SelectionDAG
&DAG
, int Enabled
,
679 int &ExtraSteps
) const override
;
680 unsigned combineRepeatedFPDivisors() const override
;
682 ConstraintType
getConstraintType(StringRef Constraint
) const override
;
683 unsigned getRegisterByName(const char* RegName
, EVT VT
,
684 SelectionDAG
&DAG
) const override
;
686 /// Examine constraint string and operand type and determine a weight value.
687 /// The operand object must already have been set up with the operand type.
689 getSingleConstraintMatchWeight(AsmOperandInfo
&info
,
690 const char *constraint
) const override
;
692 std::pair
<unsigned, const TargetRegisterClass
*>
693 getRegForInlineAsmConstraint(const TargetRegisterInfo
*TRI
,
694 StringRef Constraint
, MVT VT
) const override
;
696 const char *LowerXConstraint(EVT ConstraintVT
) const override
;
698 void LowerAsmOperandForConstraint(SDValue Op
, std::string
&Constraint
,
699 std::vector
<SDValue
> &Ops
,
700 SelectionDAG
&DAG
) const override
;
702 unsigned getInlineAsmMemConstraint(StringRef ConstraintCode
) const override
{
703 if (ConstraintCode
== "Q")
704 return InlineAsm::Constraint_Q
;
705 // FIXME: clang has code for 'Ump', 'Utf', 'Usa', and 'Ush' but these are
706 // followed by llvm_unreachable so we'll leave them unimplemented in
707 // the backend for now.
708 return TargetLowering::getInlineAsmMemConstraint(ConstraintCode
);
711 bool isUsedByReturnOnly(SDNode
*N
, SDValue
&Chain
) const override
;
712 bool mayBeEmittedAsTailCall(const CallInst
*CI
) const override
;
713 bool getIndexedAddressParts(SDNode
*Op
, SDValue
&Base
, SDValue
&Offset
,
714 ISD::MemIndexedMode
&AM
, bool &IsInc
,
715 SelectionDAG
&DAG
) const;
716 bool getPreIndexedAddressParts(SDNode
*N
, SDValue
&Base
, SDValue
&Offset
,
717 ISD::MemIndexedMode
&AM
,
718 SelectionDAG
&DAG
) const override
;
719 bool getPostIndexedAddressParts(SDNode
*N
, SDNode
*Op
, SDValue
&Base
,
720 SDValue
&Offset
, ISD::MemIndexedMode
&AM
,
721 SelectionDAG
&DAG
) const override
;
723 void ReplaceNodeResults(SDNode
*N
, SmallVectorImpl
<SDValue
> &Results
,
724 SelectionDAG
&DAG
) const override
;
726 bool shouldNormalizeToSelectSequence(LLVMContext
&, EVT
) const override
;
728 void finalizeLowering(MachineFunction
&MF
) const override
;
732 FastISel
*createFastISel(FunctionLoweringInfo
&funcInfo
,
733 const TargetLibraryInfo
*libInfo
);
734 } // end namespace AArch64
736 } // end namespace llvm