1 //===-- HexagonISelLowering.h - Hexagon 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 Hexagon uses to lower LLVM code into a
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
15 #define LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
18 #include "MCTargetDesc/HexagonMCTargetDesc.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/CodeGen/ISDOpcodes.h"
21 #include "llvm/CodeGen/SelectionDAGNodes.h"
22 #include "llvm/CodeGen/TargetLowering.h"
23 #include "llvm/CodeGen/ValueTypes.h"
24 #include "llvm/CodeGenTypes/MachineValueType.h"
25 #include "llvm/IR/CallingConv.h"
26 #include "llvm/IR/InlineAsm.h"
32 namespace HexagonISD
{
34 enum NodeType
: unsigned {
35 OP_BEGIN
= ISD::BUILTIN_OP_END
,
38 CONST32_GP
, // For marking data present in GP.
39 ADDC
, // Add with carry: (X, Y, Cin) -> (X+Y, Cout).
40 SUBC
, // Sub with carry: (X, Y, Cin) -> (X+~Y+Cin, Cout).
43 AT_GOT
, // Index in GOT.
44 AT_PCREL
, // Offset relative to PC.
46 CALL
, // Function call.
47 CALLnr
, // Function call that does not return.
50 RET_GLUE
, // Return with a glue operand.
51 BARRIER
, // Memory barrier.
56 VASL
, // Vector shifts by a scalar value
59 MFSHL
, // Funnel shifts with the shift amount guaranteed to be
60 MFSHR
, // within the range of the bit width of the element.
62 SSAT
, // Signed saturate.
63 USAT
, // Unsigned saturate.
64 SMUL_LOHI
, // Same as ISD::SMUL_LOHI, but opaque to the combiner.
65 UMUL_LOHI
, // Same as ISD::UMUL_LOHI, but opaque to the combiner.
66 // We want to legalize MULH[SU] to [SU]MUL_LOHI, but the
67 // combiner will keep rewriting it back to MULH[SU].
68 USMUL_LOHI
, // Like SMUL_LOHI, but unsigned*signed.
83 D2P
, // Convert 8-byte value to 8-bit predicate register. [*]
84 P2D
, // Convert 8-bit predicate register to 8-byte value. [*]
85 V2Q
, // Convert HVX vector to a vector predicate reg. [*]
86 Q2V
, // Convert vector predicate to an HVX vector. [*]
87 // [*] The equivalence is defined as "Q <=> (V != 0)",
88 // where the != operation compares bytes.
89 // Note: V != 0 is implemented as V >u 0.
94 TL_EXTEND
, // Wrappers for ISD::*_EXTEND and ISD::TRUNCATE to prevent DAG
95 TL_TRUNCATE
, // from auto-folding operations, e.g.
96 // (i32 ext (i16 ext i8)) would be folded to (i32 ext i8).
97 // To simplify the type legalization, we want to keep these
98 // single steps separate during type legalization.
99 // TL_[EXTEND|TRUNCATE] Inp, i128 _, i32 Opc
100 // * Inp is the original input to extend/truncate,
101 // * _ is a dummy operand with an illegal type (can be undef),
102 // * Opc is the original opcode.
103 // The legalization process (in Hexagon lowering code) will
104 // first deal with the "real" types (i.e. Inp and the result),
105 // and once all of them are processed, the wrapper node will
106 // be replaced with the original ISD node. The dummy illegal
107 // operand is there to make sure that the legalization hooks
108 // are called again after everything else is legal, giving
109 // us the opportunity to undo the wrapping.
111 TYPECAST
, // No-op that's used to convert between different legal
112 // types in a register.
113 VALIGN
, // Align two vectors (in Op0, Op1) to one that would have
114 // been loaded from address in Op2.
115 VALIGNADDR
, // Align vector address: Op0 & -Op1, except when it is
116 // an address in a vector load, then it's a no-op.
117 ISEL
, // Marker for nodes that were created during ISel, and
118 // which need explicit selection (would have been left
119 // unselected otherwise).
123 } // end namespace HexagonISD
125 class HexagonSubtarget
;
127 class HexagonTargetLowering
: public TargetLowering
{
128 int VarArgsFrameOffset
; // Frame offset to start of varargs area.
129 const HexagonTargetMachine
&HTM
;
130 const HexagonSubtarget
&Subtarget
;
133 explicit HexagonTargetLowering(const TargetMachine
&TM
,
134 const HexagonSubtarget
&ST
);
136 /// IsEligibleForTailCallOptimization - Check whether the call is eligible
137 /// for tail call optimization. Targets which want to do tail call
138 /// optimization should implement this function.
139 bool IsEligibleForTailCallOptimization(SDValue Callee
,
140 CallingConv::ID CalleeCC
, bool isVarArg
, bool isCalleeStructRet
,
141 bool isCallerStructRet
, const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
142 const SmallVectorImpl
<SDValue
> &OutVals
,
143 const SmallVectorImpl
<ISD::InputArg
> &Ins
, SelectionDAG
& DAG
) const;
145 bool getTgtMemIntrinsic(IntrinsicInfo
&Info
, const CallInst
&I
,
147 unsigned Intrinsic
) const override
;
149 bool isTruncateFree(Type
*Ty1
, Type
*Ty2
) const override
;
150 bool isTruncateFree(EVT VT1
, EVT VT2
) const override
;
152 bool isCheapToSpeculateCttz(Type
*) const override
{ return true; }
153 bool isCheapToSpeculateCtlz(Type
*) const override
{ return true; }
154 bool isCtlzFast() const override
{ return true; }
156 bool hasBitTest(SDValue X
, SDValue Y
) const override
;
158 bool allowTruncateForTailCall(Type
*Ty1
, Type
*Ty2
) const override
;
160 /// Return true if an FMA operation is faster than a pair of mul and add
161 /// instructions. fmuladd intrinsics will be expanded to FMAs when this
162 /// method returns true (and FMAs are legal), otherwise fmuladd is
163 /// expanded to mul + add.
164 bool isFMAFasterThanFMulAndFAdd(const MachineFunction
&,
167 // Should we expand the build vector with shuffles?
168 bool shouldExpandBuildVectorWithShuffles(EVT VT
,
169 unsigned DefinedValues
) const override
;
170 bool isExtractSubvectorCheap(EVT ResVT
, EVT SrcVT
,
171 unsigned Index
) const override
;
173 bool isTargetCanonicalConstantNode(SDValue Op
) const override
;
175 bool isShuffleMaskLegal(ArrayRef
<int> Mask
, EVT VT
) const override
;
176 LegalizeTypeAction
getPreferredVectorAction(MVT VT
) const override
;
177 LegalizeAction
getCustomOperationAction(SDNode
&Op
) const override
;
179 SDValue
LowerOperation(SDValue Op
, SelectionDAG
&DAG
) const override
;
180 void LowerOperationWrapper(SDNode
*N
, SmallVectorImpl
<SDValue
> &Results
,
181 SelectionDAG
&DAG
) const override
;
182 void ReplaceNodeResults(SDNode
*N
, SmallVectorImpl
<SDValue
> &Results
,
183 SelectionDAG
&DAG
) const override
;
185 const char *getTargetNodeName(unsigned Opcode
) const override
;
187 SDValue
LowerBUILD_VECTOR(SDValue Op
, SelectionDAG
&DAG
) const;
188 SDValue
LowerCONCAT_VECTORS(SDValue Op
, SelectionDAG
&DAG
) const;
189 SDValue
LowerEXTRACT_VECTOR_ELT(SDValue Op
, SelectionDAG
&DAG
) const;
190 SDValue
LowerEXTRACT_SUBVECTOR(SDValue Op
, SelectionDAG
&DAG
) const;
191 SDValue
LowerINSERT_VECTOR_ELT(SDValue Op
, SelectionDAG
&DAG
) const;
192 SDValue
LowerINSERT_SUBVECTOR(SDValue Op
, SelectionDAG
&DAG
) const;
193 SDValue
LowerVECTOR_SHUFFLE(SDValue Op
, SelectionDAG
&DAG
) const;
194 SDValue
LowerVECTOR_SHIFT(SDValue Op
, SelectionDAG
&DAG
) const;
195 SDValue
LowerROTL(SDValue Op
, SelectionDAG
&DAG
) const;
196 SDValue
LowerBITCAST(SDValue Op
, SelectionDAG
&DAG
) const;
197 SDValue
LowerANY_EXTEND(SDValue Op
, SelectionDAG
&DAG
) const;
198 SDValue
LowerSIGN_EXTEND(SDValue Op
, SelectionDAG
&DAG
) const;
199 SDValue
LowerZERO_EXTEND(SDValue Op
, SelectionDAG
&DAG
) const;
200 SDValue
LowerLoad(SDValue Op
, SelectionDAG
&DAG
) const;
201 SDValue
LowerStore(SDValue Op
, SelectionDAG
&DAG
) const;
202 SDValue
LowerUnalignedLoad(SDValue Op
, SelectionDAG
&DAG
) const;
203 SDValue
LowerUAddSubO(SDValue Op
, SelectionDAG
&DAG
) const;
204 SDValue
LowerUAddSubOCarry(SDValue Op
, SelectionDAG
&DAG
) const;
206 SDValue
LowerDYNAMIC_STACKALLOC(SDValue Op
, SelectionDAG
&DAG
) const;
207 SDValue
LowerINLINEASM(SDValue Op
, SelectionDAG
&DAG
) const;
208 SDValue
LowerFDIV(SDValue Op
, SelectionDAG
&DAG
) const;
209 SDValue
LowerPREFETCH(SDValue Op
, SelectionDAG
&DAG
) const;
210 SDValue
LowerREADCYCLECOUNTER(SDValue Op
, SelectionDAG
&DAG
) const;
211 SDValue
LowerREADSTEADYCOUNTER(SDValue Op
, SelectionDAG
&DAG
) const;
212 SDValue
LowerEH_LABEL(SDValue Op
, SelectionDAG
&DAG
) const;
213 SDValue
LowerEH_RETURN(SDValue Op
, SelectionDAG
&DAG
) const;
215 LowerFormalArguments(SDValue Chain
, CallingConv::ID CallConv
, bool isVarArg
,
216 const SmallVectorImpl
<ISD::InputArg
> &Ins
,
217 const SDLoc
&dl
, SelectionDAG
&DAG
,
218 SmallVectorImpl
<SDValue
> &InVals
) const override
;
219 SDValue
LowerGLOBALADDRESS(SDValue Op
, SelectionDAG
&DAG
) const;
220 SDValue
LowerBlockAddress(SDValue Op
, SelectionDAG
&DAG
) const;
221 SDValue
LowerGlobalTLSAddress(SDValue Op
, SelectionDAG
&DAG
) const;
222 SDValue
LowerToTLSGeneralDynamicModel(GlobalAddressSDNode
*GA
,
223 SelectionDAG
&DAG
) const;
224 SDValue
LowerToTLSInitialExecModel(GlobalAddressSDNode
*GA
,
225 SelectionDAG
&DAG
) const;
226 SDValue
LowerToTLSLocalExecModel(GlobalAddressSDNode
*GA
,
227 SelectionDAG
&DAG
) const;
228 SDValue
GetDynamicTLSAddr(SelectionDAG
&DAG
, SDValue Chain
,
229 GlobalAddressSDNode
*GA
, SDValue InGlue
, EVT PtrVT
,
230 unsigned ReturnReg
, unsigned char OperandGlues
) const;
231 SDValue
LowerGLOBAL_OFFSET_TABLE(SDValue Op
, SelectionDAG
&DAG
) const;
233 SDValue
LowerCall(TargetLowering::CallLoweringInfo
&CLI
,
234 SmallVectorImpl
<SDValue
> &InVals
) const override
;
235 SDValue
LowerCallResult(SDValue Chain
, SDValue InGlue
,
236 CallingConv::ID CallConv
, bool isVarArg
,
237 const SmallVectorImpl
<ISD::InputArg
> &Ins
,
238 const SDLoc
&dl
, SelectionDAG
&DAG
,
239 SmallVectorImpl
<SDValue
> &InVals
,
240 const SmallVectorImpl
<SDValue
> &OutVals
,
241 SDValue Callee
) const;
243 SDValue
LowerSETCC(SDValue Op
, SelectionDAG
&DAG
) const;
244 SDValue
LowerVSELECT(SDValue Op
, SelectionDAG
&DAG
) const;
245 SDValue
LowerFRAMEADDR(SDValue Op
, SelectionDAG
&DAG
) const;
246 SDValue
LowerATOMIC_FENCE(SDValue Op
, SelectionDAG
& DAG
) const;
247 SDValue
LowerRETURNADDR(SDValue Op
, SelectionDAG
&DAG
) const;
249 bool CanLowerReturn(CallingConv::ID CallConv
,
250 MachineFunction
&MF
, bool isVarArg
,
251 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
252 LLVMContext
&Context
, const Type
*RetTy
) const override
;
254 SDValue
LowerReturn(SDValue Chain
, CallingConv::ID CallConv
, bool isVarArg
,
255 const SmallVectorImpl
<ISD::OutputArg
> &Outs
,
256 const SmallVectorImpl
<SDValue
> &OutVals
,
257 const SDLoc
&dl
, SelectionDAG
&DAG
) const override
;
259 SDValue
PerformDAGCombine(SDNode
*N
, DAGCombinerInfo
&DCI
) const override
;
261 bool mayBeEmittedAsTailCall(const CallInst
*CI
) const override
;
263 Register
getRegisterByName(const char* RegName
, LLT VT
,
264 const MachineFunction
&MF
) const override
;
266 /// If a physical register, this returns the register that receives the
267 /// exception address on entry to an EH pad.
269 getExceptionPointerRegister(const Constant
*PersonalityFn
) const override
{
273 /// If a physical register, this returns the register that receives the
274 /// exception typeid on entry to a landing pad.
276 getExceptionSelectorRegister(const Constant
*PersonalityFn
) const override
{
280 SDValue
LowerVASTART(SDValue Op
, SelectionDAG
&DAG
) const;
281 SDValue
LowerVACOPY(SDValue Op
, SelectionDAG
&DAG
) const;
282 SDValue
LowerConstantPool(SDValue Op
, SelectionDAG
&DAG
) const;
283 SDValue
LowerJumpTable(SDValue Op
, SelectionDAG
&DAG
) const;
285 EVT
getSetCCResultType(const DataLayout
&, LLVMContext
&C
,
286 EVT VT
) const override
{
290 return EVT::getVectorVT(C
, MVT::i1
, VT
.getVectorNumElements());
293 bool getPostIndexedAddressParts(SDNode
*N
, SDNode
*Op
,
294 SDValue
&Base
, SDValue
&Offset
,
295 ISD::MemIndexedMode
&AM
,
296 SelectionDAG
&DAG
) const override
;
298 ConstraintType
getConstraintType(StringRef Constraint
) const override
;
300 std::pair
<unsigned, const TargetRegisterClass
*>
301 getRegForInlineAsmConstraint(const TargetRegisterInfo
*TRI
,
302 StringRef Constraint
, MVT VT
) const override
;
305 SDValue
LowerINTRINSIC_WO_CHAIN(SDValue Op
, SelectionDAG
&DAG
) const;
306 SDValue
LowerINTRINSIC_VOID(SDValue Op
, SelectionDAG
&DAG
) const;
307 /// isLegalAddressingMode - Return true if the addressing mode represented
308 /// by AM is legal for this target, for a load/store of the specified type.
309 /// The type may be VoidTy, in which case only return true if the addressing
310 /// mode is legal for a load/store of any legal type.
311 /// TODO: Handle pre/postinc as well.
312 bool isLegalAddressingMode(const DataLayout
&DL
, const AddrMode
&AM
,
313 Type
*Ty
, unsigned AS
,
314 Instruction
*I
= nullptr) const override
;
315 /// Return true if folding a constant offset with the given GlobalAddress
316 /// is legal. It is frequently not legal in PIC relocation models.
317 bool isOffsetFoldingLegal(const GlobalAddressSDNode
*GA
) const override
;
319 bool isFPImmLegal(const APFloat
&Imm
, EVT VT
,
320 bool ForCodeSize
) const override
;
322 /// isLegalICmpImmediate - Return true if the specified immediate is legal
323 /// icmp immediate, that is the target has icmp instructions which can
324 /// compare a register against the immediate without having to materialize
325 /// the immediate into a register.
326 bool isLegalICmpImmediate(int64_t Imm
) const override
;
328 EVT
getOptimalMemOpType(const MemOp
&Op
,
329 const AttributeList
&FuncAttributes
) const override
;
331 bool allowsMemoryAccess(LLVMContext
&Context
, const DataLayout
&DL
, EVT VT
,
332 unsigned AddrSpace
, Align Alignment
,
333 MachineMemOperand::Flags Flags
,
334 unsigned *Fast
) const override
;
336 bool allowsMisalignedMemoryAccesses(EVT VT
, unsigned AddrSpace
,
338 MachineMemOperand::Flags Flags
,
339 unsigned *Fast
) const override
;
341 /// Returns relocation base for the given PIC jumptable.
342 SDValue
getPICJumpTableRelocBase(SDValue Table
, SelectionDAG
&DAG
)
345 bool shouldReduceLoadWidth(SDNode
*Load
, ISD::LoadExtType ExtTy
,
346 EVT NewVT
) const override
;
348 void AdjustInstrPostInstrSelection(MachineInstr
&MI
,
349 SDNode
*Node
) const override
;
351 // Handling of atomic RMW instructions.
352 Value
*emitLoadLinked(IRBuilderBase
&Builder
, Type
*ValueTy
, Value
*Addr
,
353 AtomicOrdering Ord
) const override
;
354 Value
*emitStoreConditional(IRBuilderBase
&Builder
, Value
*Val
, Value
*Addr
,
355 AtomicOrdering Ord
) const override
;
356 AtomicExpansionKind
shouldExpandAtomicLoadInIR(LoadInst
*LI
) const override
;
357 AtomicExpansionKind
shouldExpandAtomicStoreInIR(StoreInst
*SI
) const override
;
359 shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst
*AI
) const override
;
362 shouldExpandAtomicRMWInIR(AtomicRMWInst
*AI
) const override
{
363 return AtomicExpansionKind::LLSC
;
367 void initializeHVXLowering();
368 unsigned getPreferredHvxVectorAction(MVT VecTy
) const;
369 unsigned getCustomHvxOperationAction(SDNode
&Op
) const;
371 bool validateConstPtrAlignment(SDValue Ptr
, Align NeedAlign
, const SDLoc
&dl
,
372 SelectionDAG
&DAG
) const;
373 SDValue
replaceMemWithUndef(SDValue Op
, SelectionDAG
&DAG
) const;
375 std::pair
<SDValue
,int> getBaseAndOffset(SDValue Addr
) const;
377 bool getBuildVectorConstInts(ArrayRef
<SDValue
> Values
, MVT VecTy
,
379 MutableArrayRef
<ConstantInt
*> Consts
) const;
380 SDValue
buildVector32(ArrayRef
<SDValue
> Elem
, const SDLoc
&dl
, MVT VecTy
,
381 SelectionDAG
&DAG
) const;
382 SDValue
buildVector64(ArrayRef
<SDValue
> Elem
, const SDLoc
&dl
, MVT VecTy
,
383 SelectionDAG
&DAG
) const;
384 SDValue
extractVector(SDValue VecV
, SDValue IdxV
, const SDLoc
&dl
,
385 MVT ValTy
, MVT ResTy
, SelectionDAG
&DAG
) const;
386 SDValue
extractVectorPred(SDValue VecV
, SDValue IdxV
, const SDLoc
&dl
,
387 MVT ValTy
, MVT ResTy
, SelectionDAG
&DAG
) const;
388 SDValue
insertVector(SDValue VecV
, SDValue ValV
, SDValue IdxV
,
389 const SDLoc
&dl
, MVT ValTy
, SelectionDAG
&DAG
) const;
390 SDValue
insertVectorPred(SDValue VecV
, SDValue ValV
, SDValue IdxV
,
391 const SDLoc
&dl
, MVT ValTy
, SelectionDAG
&DAG
) const;
392 SDValue
expandPredicate(SDValue Vec32
, const SDLoc
&dl
,
393 SelectionDAG
&DAG
) const;
394 SDValue
contractPredicate(SDValue Vec64
, const SDLoc
&dl
,
395 SelectionDAG
&DAG
) const;
396 SDValue
getSplatValue(SDValue Op
, SelectionDAG
&DAG
) const;
397 SDValue
getVectorShiftByInt(SDValue Op
, SelectionDAG
&DAG
) const;
398 SDValue
appendUndef(SDValue Val
, MVT ResTy
, SelectionDAG
&DAG
) const;
399 SDValue
getCombine(SDValue Hi
, SDValue Lo
, const SDLoc
&dl
, MVT ResTy
,
400 SelectionDAG
&DAG
) const;
402 bool isUndef(SDValue Op
) const {
403 if (Op
.isMachineOpcode())
404 return Op
.getMachineOpcode() == TargetOpcode::IMPLICIT_DEF
;
405 return Op
.getOpcode() == ISD::UNDEF
;
407 SDValue
getInstr(unsigned MachineOpc
, const SDLoc
&dl
, MVT Ty
,
408 ArrayRef
<SDValue
> Ops
, SelectionDAG
&DAG
) const {
409 SDNode
*N
= DAG
.getMachineNode(MachineOpc
, dl
, Ty
, Ops
);
410 return SDValue(N
, 0);
412 SDValue
getZero(const SDLoc
&dl
, MVT Ty
, SelectionDAG
&DAG
) const;
414 using VectorPair
= std::pair
<SDValue
, SDValue
>;
415 using TypePair
= std::pair
<MVT
, MVT
>;
417 SDValue
getInt(unsigned IntId
, MVT ResTy
, ArrayRef
<SDValue
> Ops
,
418 const SDLoc
&dl
, SelectionDAG
&DAG
) const;
420 MVT
ty(SDValue Op
) const {
421 return Op
.getValueType().getSimpleVT();
423 TypePair
ty(const VectorPair
&Ops
) const {
424 return { Ops
.first
.getValueType().getSimpleVT(),
425 Ops
.second
.getValueType().getSimpleVT() };
427 MVT
tyScalar(MVT Ty
) const {
430 return MVT::getIntegerVT(Ty
.getSizeInBits());
432 MVT
tyVector(MVT Ty
, MVT ElemTy
) const {
433 if (Ty
.isVector() && Ty
.getVectorElementType() == ElemTy
)
435 unsigned TyWidth
= Ty
.getSizeInBits();
436 unsigned ElemWidth
= ElemTy
.getSizeInBits();
437 assert((TyWidth
% ElemWidth
) == 0);
438 return MVT::getVectorVT(ElemTy
, TyWidth
/ElemWidth
);
441 MVT
typeJoin(const TypePair
&Tys
) const;
442 TypePair
typeSplit(MVT Ty
) const;
443 MVT
typeExtElem(MVT VecTy
, unsigned Factor
) const;
444 MVT
typeTruncElem(MVT VecTy
, unsigned Factor
) const;
445 TypePair
typeExtendToWider(MVT Ty0
, MVT Ty1
) const;
446 TypePair
typeWidenToWider(MVT Ty0
, MVT Ty1
) const;
447 MVT
typeLegalize(MVT Ty
, SelectionDAG
&DAG
) const;
448 MVT
typeWidenToHvx(MVT Ty
) const;
450 SDValue
opJoin(const VectorPair
&Ops
, const SDLoc
&dl
,
451 SelectionDAG
&DAG
) const;
452 VectorPair
opSplit(SDValue Vec
, const SDLoc
&dl
, SelectionDAG
&DAG
) const;
453 SDValue
opCastElem(SDValue Vec
, MVT ElemTy
, SelectionDAG
&DAG
) const;
455 SDValue
LoHalf(SDValue V
, SelectionDAG
&DAG
) const {
458 if (!Ty
.isVector()) {
459 assert(Ty
.getSizeInBits() == 64);
460 return DAG
.getTargetExtractSubreg(Hexagon::isub_lo
, dl
, MVT::i32
, V
);
462 MVT HalfTy
= typeSplit(Ty
).first
;
463 SDValue Idx
= getZero(dl
, MVT::i32
, DAG
);
464 return DAG
.getNode(ISD::EXTRACT_SUBVECTOR
, dl
, HalfTy
, V
, Idx
);
466 SDValue
HiHalf(SDValue V
, SelectionDAG
&DAG
) const {
469 if (!Ty
.isVector()) {
470 assert(Ty
.getSizeInBits() == 64);
471 return DAG
.getTargetExtractSubreg(Hexagon::isub_hi
, dl
, MVT::i32
, V
);
473 MVT HalfTy
= typeSplit(Ty
).first
;
474 SDValue Idx
= DAG
.getConstant(HalfTy
.getVectorNumElements(), dl
, MVT::i32
);
475 return DAG
.getNode(ISD::EXTRACT_SUBVECTOR
, dl
, HalfTy
, V
, Idx
);
478 bool allowsHvxMemoryAccess(MVT VecTy
, MachineMemOperand::Flags Flags
,
479 unsigned *Fast
) const;
480 bool allowsHvxMisalignedMemoryAccesses(MVT VecTy
,
481 MachineMemOperand::Flags Flags
,
482 unsigned *Fast
) const;
483 void AdjustHvxInstrPostInstrSelection(MachineInstr
&MI
, SDNode
*Node
) const;
485 bool isHvxSingleTy(MVT Ty
) const;
486 bool isHvxPairTy(MVT Ty
) const;
487 bool isHvxBoolTy(MVT Ty
) const;
488 SDValue
convertToByteIndex(SDValue ElemIdx
, MVT ElemTy
,
489 SelectionDAG
&DAG
) const;
490 SDValue
getIndexInWord32(SDValue Idx
, MVT ElemTy
, SelectionDAG
&DAG
) const;
491 SDValue
getByteShuffle(const SDLoc
&dl
, SDValue Op0
, SDValue Op1
,
492 ArrayRef
<int> Mask
, SelectionDAG
&DAG
) const;
494 SDValue
buildHvxVectorReg(ArrayRef
<SDValue
> Values
, const SDLoc
&dl
,
495 MVT VecTy
, SelectionDAG
&DAG
) const;
496 SDValue
buildHvxVectorPred(ArrayRef
<SDValue
> Values
, const SDLoc
&dl
,
497 MVT VecTy
, SelectionDAG
&DAG
) const;
498 SDValue
createHvxPrefixPred(SDValue PredV
, const SDLoc
&dl
,
499 unsigned BitBytes
, bool ZeroFill
,
500 SelectionDAG
&DAG
) const;
501 SDValue
extractHvxElementReg(SDValue VecV
, SDValue IdxV
, const SDLoc
&dl
,
502 MVT ResTy
, SelectionDAG
&DAG
) const;
503 SDValue
extractHvxElementPred(SDValue VecV
, SDValue IdxV
, const SDLoc
&dl
,
504 MVT ResTy
, SelectionDAG
&DAG
) const;
505 SDValue
insertHvxElementReg(SDValue VecV
, SDValue IdxV
, SDValue ValV
,
506 const SDLoc
&dl
, SelectionDAG
&DAG
) const;
507 SDValue
insertHvxElementPred(SDValue VecV
, SDValue IdxV
, SDValue ValV
,
508 const SDLoc
&dl
, SelectionDAG
&DAG
) const;
509 SDValue
extractHvxSubvectorReg(SDValue OrigOp
, SDValue VecV
, SDValue IdxV
,
510 const SDLoc
&dl
, MVT ResTy
, SelectionDAG
&DAG
)
512 SDValue
extractHvxSubvectorPred(SDValue VecV
, SDValue IdxV
, const SDLoc
&dl
,
513 MVT ResTy
, SelectionDAG
&DAG
) const;
514 SDValue
insertHvxSubvectorReg(SDValue VecV
, SDValue SubV
, SDValue IdxV
,
515 const SDLoc
&dl
, SelectionDAG
&DAG
) const;
516 SDValue
insertHvxSubvectorPred(SDValue VecV
, SDValue SubV
, SDValue IdxV
,
517 const SDLoc
&dl
, SelectionDAG
&DAG
) const;
518 SDValue
extendHvxVectorPred(SDValue VecV
, const SDLoc
&dl
, MVT ResTy
,
519 bool ZeroExt
, SelectionDAG
&DAG
) const;
520 SDValue
compressHvxPred(SDValue VecQ
, const SDLoc
&dl
, MVT ResTy
,
521 SelectionDAG
&DAG
) const;
522 SDValue
resizeToWidth(SDValue VecV
, MVT ResTy
, bool Signed
, const SDLoc
&dl
,
523 SelectionDAG
&DAG
) const;
524 SDValue
extractSubvector(SDValue Vec
, MVT SubTy
, unsigned SubIdx
,
525 SelectionDAG
&DAG
) const;
526 VectorPair
emitHvxAddWithOverflow(SDValue A
, SDValue B
, const SDLoc
&dl
,
527 bool Signed
, SelectionDAG
&DAG
) const;
528 VectorPair
emitHvxShiftRightRnd(SDValue Val
, unsigned Amt
, bool Signed
,
529 SelectionDAG
&DAG
) const;
530 SDValue
emitHvxMulHsV60(SDValue A
, SDValue B
, const SDLoc
&dl
,
531 SelectionDAG
&DAG
) const;
532 SDValue
emitHvxMulLoHiV60(SDValue A
, bool SignedA
, SDValue B
, bool SignedB
,
533 const SDLoc
&dl
, SelectionDAG
&DAG
) const;
534 SDValue
emitHvxMulLoHiV62(SDValue A
, bool SignedA
, SDValue B
, bool SignedB
,
535 const SDLoc
&dl
, SelectionDAG
&DAG
) const;
537 SDValue
LowerHvxBuildVector(SDValue Op
, SelectionDAG
&DAG
) const;
538 SDValue
LowerHvxSplatVector(SDValue Op
, SelectionDAG
&DAG
) const;
539 SDValue
LowerHvxConcatVectors(SDValue Op
, SelectionDAG
&DAG
) const;
540 SDValue
LowerHvxExtractElement(SDValue Op
, SelectionDAG
&DAG
) const;
541 SDValue
LowerHvxInsertElement(SDValue Op
, SelectionDAG
&DAG
) const;
542 SDValue
LowerHvxExtractSubvector(SDValue Op
, SelectionDAG
&DAG
) const;
543 SDValue
LowerHvxInsertSubvector(SDValue Op
, SelectionDAG
&DAG
) const;
544 SDValue
LowerHvxBitcast(SDValue Op
, SelectionDAG
&DAG
) const;
545 SDValue
LowerHvxAnyExt(SDValue Op
, SelectionDAG
&DAG
) const;
546 SDValue
LowerHvxSignExt(SDValue Op
, SelectionDAG
&DAG
) const;
547 SDValue
LowerHvxZeroExt(SDValue Op
, SelectionDAG
&DAG
) const;
548 SDValue
LowerHvxCttz(SDValue Op
, SelectionDAG
&DAG
) const;
549 SDValue
LowerHvxMulh(SDValue Op
, SelectionDAG
&DAG
) const;
550 SDValue
LowerHvxMulLoHi(SDValue Op
, SelectionDAG
&DAG
) const;
551 SDValue
LowerHvxExtend(SDValue Op
, SelectionDAG
&DAG
) const;
552 SDValue
LowerHvxSelect(SDValue Op
, SelectionDAG
&DAG
) const;
553 SDValue
LowerHvxShift(SDValue Op
, SelectionDAG
&DAG
) const;
554 SDValue
LowerHvxFunnelShift(SDValue Op
, SelectionDAG
&DAG
) const;
555 SDValue
LowerHvxIntrinsic(SDValue Op
, SelectionDAG
&DAG
) const;
556 SDValue
LowerHvxMaskedOp(SDValue Op
, SelectionDAG
&DAG
) const;
557 SDValue
LowerHvxFpExtend(SDValue Op
, SelectionDAG
&DAG
) const;
558 SDValue
LowerHvxFpToInt(SDValue Op
, SelectionDAG
&DAG
) const;
559 SDValue
LowerHvxIntToFp(SDValue Op
, SelectionDAG
&DAG
) const;
560 SDValue
ExpandHvxFpToInt(SDValue Op
, SelectionDAG
&DAG
) const;
561 SDValue
ExpandHvxIntToFp(SDValue Op
, SelectionDAG
&DAG
) const;
563 VectorPair
SplitVectorOp(SDValue Op
, SelectionDAG
&DAG
) const;
565 SDValue
SplitHvxMemOp(SDValue Op
, SelectionDAG
&DAG
) const;
566 SDValue
WidenHvxLoad(SDValue Op
, SelectionDAG
&DAG
) const;
567 SDValue
WidenHvxStore(SDValue Op
, SelectionDAG
&DAG
) const;
568 SDValue
WidenHvxSetCC(SDValue Op
, SelectionDAG
&DAG
) const;
569 SDValue
LegalizeHvxResize(SDValue Op
, SelectionDAG
&DAG
) const;
570 SDValue
ExpandHvxResizeIntoSteps(SDValue Op
, SelectionDAG
&DAG
) const;
571 SDValue
EqualizeFpIntConversion(SDValue Op
, SelectionDAG
&DAG
) const;
573 SDValue
CreateTLWrapper(SDValue Op
, SelectionDAG
&DAG
) const;
574 SDValue
RemoveTLWrapper(SDValue Op
, SelectionDAG
&DAG
) const;
576 std::pair
<const TargetRegisterClass
*, uint8_t>
577 findRepresentativeClass(const TargetRegisterInfo
*TRI
, MVT VT
)
580 bool shouldSplitToHvx(MVT Ty
, SelectionDAG
&DAG
) const;
581 bool shouldWidenToHvx(MVT Ty
, SelectionDAG
&DAG
) const;
582 bool isHvxOperation(SDNode
*N
, SelectionDAG
&DAG
) const;
583 SDValue
LowerHvxOperation(SDValue Op
, SelectionDAG
&DAG
) const;
584 void LowerHvxOperationWrapper(SDNode
*N
, SmallVectorImpl
<SDValue
> &Results
,
585 SelectionDAG
&DAG
) const;
586 void ReplaceHvxNodeResults(SDNode
*N
, SmallVectorImpl
<SDValue
> &Results
,
587 SelectionDAG
&DAG
) const;
589 SDValue
combineTruncateBeforeLegal(SDValue Op
, DAGCombinerInfo
&DCI
) const;
590 SDValue
combineConcatVectorsBeforeLegal(SDValue Op
, DAGCombinerInfo
& DCI
)
592 SDValue
combineVectorShuffleBeforeLegal(SDValue Op
, DAGCombinerInfo
& DCI
)
595 SDValue
PerformHvxDAGCombine(SDNode
* N
, DAGCombinerInfo
& DCI
) const;
598 } // end namespace llvm
600 #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H