xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Hexagon/HexagonISelLowering.h (revision a7dea1671b87c07d2d266f836bfa8b58efc7c134)
1 //===-- HexagonISelLowering.h - Hexagon 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 Hexagon uses to lower LLVM code into a
10 // selection DAG.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
15 #define LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
16 
17 #include "Hexagon.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/CodeGen/ISDOpcodes.h"
20 #include "llvm/CodeGen/SelectionDAGNodes.h"
21 #include "llvm/CodeGen/TargetLowering.h"
22 #include "llvm/CodeGen/ValueTypes.h"
23 #include "llvm/IR/CallingConv.h"
24 #include "llvm/IR/InlineAsm.h"
25 #include "llvm/Support/MachineValueType.h"
26 #include <cstdint>
27 #include <utility>
28 
29 namespace llvm {
30 
31 namespace HexagonISD {
32 
33     enum NodeType : unsigned {
34       OP_BEGIN = ISD::BUILTIN_OP_END,
35 
36       CONST32 = OP_BEGIN,
37       CONST32_GP,  // For marking data present in GP.
38       ADDC,        // Add with carry: (X, Y, Cin) -> (X+Y, Cout).
39       SUBC,        // Sub with carry: (X, Y, Cin) -> (X+~Y+Cin, Cout).
40       ALLOCA,
41 
42       AT_GOT,      // Index in GOT.
43       AT_PCREL,    // Offset relative to PC.
44 
45       CALL,        // Function call.
46       CALLnr,      // Function call that does not return.
47       CALLR,
48 
49       RET_FLAG,    // Return with a flag operand.
50       BARRIER,     // Memory barrier.
51       JT,          // Jump table.
52       CP,          // Constant pool.
53 
54       COMBINE,
55       VSPLAT,      // Generic splat, selection depends on argument/return
56                    // types.
57       VASL,
58       VASR,
59       VLSR,
60 
61       TSTBIT,
62       INSERT,
63       EXTRACTU,
64       VEXTRACTW,
65       VINSERTW0,
66       VROR,
67       TC_RETURN,
68       EH_RETURN,
69       DCFETCH,
70       READCYCLE,
71       PTRUE,
72       PFALSE,
73       D2P,         // Convert 8-byte value to 8-bit predicate register. [*]
74       P2D,         // Convert 8-bit predicate register to 8-byte value. [*]
75       V2Q,         // Convert HVX vector to a vector predicate reg. [*]
76       Q2V,         // Convert vector predicate to an HVX vector. [*]
77                    // [*] The equivalence is defined as "Q <=> (V != 0)",
78                    //     where the != operation compares bytes.
79                    // Note: V != 0 is implemented as V >u 0.
80       QCAT,
81       QTRUE,
82       QFALSE,
83       VZERO,
84       VSPLATW,     // HVX splat of a 32-bit word with an arbitrary result type.
85       TYPECAST,    // No-op that's used to convert between different legal
86                    // types in a register.
87       VALIGN,      // Align two vectors (in Op0, Op1) to one that would have
88                    // been loaded from address in Op2.
89       VALIGNADDR,  // Align vector address: Op0 & -Op1, except when it is
90                    // an address in a vector load, then it's a no-op.
91       OP_END
92     };
93 
94 } // end namespace HexagonISD
95 
96   class HexagonSubtarget;
97 
98   class HexagonTargetLowering : public TargetLowering {
99     int VarArgsFrameOffset;   // Frame offset to start of varargs area.
100     const HexagonTargetMachine &HTM;
101     const HexagonSubtarget &Subtarget;
102 
103     bool CanReturnSmallStruct(const Function* CalleeFn, unsigned& RetSize)
104         const;
105 
106   public:
107     explicit HexagonTargetLowering(const TargetMachine &TM,
108                                    const HexagonSubtarget &ST);
109 
110     bool isHVXVectorType(MVT Ty) const;
111 
112     /// IsEligibleForTailCallOptimization - Check whether the call is eligible
113     /// for tail call optimization. Targets which want to do tail call
114     /// optimization should implement this function.
115     bool IsEligibleForTailCallOptimization(SDValue Callee,
116         CallingConv::ID CalleeCC, bool isVarArg, bool isCalleeStructRet,
117         bool isCallerStructRet, const SmallVectorImpl<ISD::OutputArg> &Outs,
118         const SmallVectorImpl<SDValue> &OutVals,
119         const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG& DAG) const;
120 
121     bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I,
122                             MachineFunction &MF,
123                             unsigned Intrinsic) const override;
124 
125     bool isTruncateFree(Type *Ty1, Type *Ty2) const override;
126     bool isTruncateFree(EVT VT1, EVT VT2) const override;
127 
128     bool isCheapToSpeculateCttz() const override { return true; }
129     bool isCheapToSpeculateCtlz() const override { return true; }
130     bool isCtlzFast() const override { return true; }
131 
132     bool hasBitTest(SDValue X, SDValue Y) const override;
133 
134     bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override;
135 
136     /// Return true if an FMA operation is faster than a pair of mul and add
137     /// instructions. fmuladd intrinsics will be expanded to FMAs when this
138     /// method returns true (and FMAs are legal), otherwise fmuladd is
139     /// expanded to mul + add.
140     bool isFMAFasterThanFMulAndFAdd(EVT) const override;
141 
142     // Should we expand the build vector with shuffles?
143     bool shouldExpandBuildVectorWithShuffles(EVT VT,
144         unsigned DefinedValues) const override;
145 
146     bool isShuffleMaskLegal(ArrayRef<int> Mask, EVT VT) const override;
147     TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT)
148         const override;
149 
150     SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
151     void LowerOperationWrapper(SDNode *N, SmallVectorImpl<SDValue> &Results,
152                                SelectionDAG &DAG) const override;
153     void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
154                             SelectionDAG &DAG) const override;
155 
156     const char *getTargetNodeName(unsigned Opcode) const override;
157 
158     SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
159     SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;
160     SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
161     SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
162     SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
163     SDValue LowerINSERT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
164     SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
165     SDValue LowerVECTOR_SHIFT(SDValue Op, SelectionDAG &DAG) const;
166     SDValue LowerROTL(SDValue Op, SelectionDAG &DAG) const;
167     SDValue LowerBITCAST(SDValue Op, SelectionDAG &DAG) const;
168     SDValue LowerANY_EXTEND(SDValue Op, SelectionDAG &DAG) const;
169     SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) const;
170     SDValue LowerZERO_EXTEND(SDValue Op, SelectionDAG &DAG) const;
171     SDValue LowerLoad(SDValue Op, SelectionDAG &DAG) const;
172     SDValue LowerStore(SDValue Op, SelectionDAG &DAG) const;
173     SDValue LowerUnalignedLoad(SDValue Op, SelectionDAG &DAG) const;
174     SDValue LowerUAddSubO(SDValue Op, SelectionDAG &DAG) const;
175     SDValue LowerAddSubCarry(SDValue Op, SelectionDAG &DAG) const;
176 
177     SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
178     SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
179     SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;
180     SDValue LowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const;
181     SDValue LowerEH_LABEL(SDValue Op, SelectionDAG &DAG) const;
182     SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
183     SDValue
184     LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
185                          const SmallVectorImpl<ISD::InputArg> &Ins,
186                          const SDLoc &dl, SelectionDAG &DAG,
187                          SmallVectorImpl<SDValue> &InVals) const override;
188     SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const;
189     SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
190     SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
191     SDValue LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
192         SelectionDAG &DAG) const;
193     SDValue LowerToTLSInitialExecModel(GlobalAddressSDNode *GA,
194         SelectionDAG &DAG) const;
195     SDValue LowerToTLSLocalExecModel(GlobalAddressSDNode *GA,
196         SelectionDAG &DAG) const;
197     SDValue GetDynamicTLSAddr(SelectionDAG &DAG, SDValue Chain,
198         GlobalAddressSDNode *GA, SDValue InFlag, EVT PtrVT,
199         unsigned ReturnReg, unsigned char OperandFlags) const;
200     SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG) const;
201 
202     SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
203         SmallVectorImpl<SDValue> &InVals) const override;
204     SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
205                             CallingConv::ID CallConv, bool isVarArg,
206                             const SmallVectorImpl<ISD::InputArg> &Ins,
207                             const SDLoc &dl, SelectionDAG &DAG,
208                             SmallVectorImpl<SDValue> &InVals,
209                             const SmallVectorImpl<SDValue> &OutVals,
210                             SDValue Callee) const;
211 
212     SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
213     SDValue LowerVSELECT(SDValue Op, SelectionDAG &DAG) const;
214     SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
215     SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
216     SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
217 
218     bool CanLowerReturn(CallingConv::ID CallConv,
219                         MachineFunction &MF, bool isVarArg,
220                         const SmallVectorImpl<ISD::OutputArg> &Outs,
221                         LLVMContext &Context) const override;
222 
223     SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
224                         const SmallVectorImpl<ISD::OutputArg> &Outs,
225                         const SmallVectorImpl<SDValue> &OutVals,
226                         const SDLoc &dl, SelectionDAG &DAG) const override;
227 
228     SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
229 
230     bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
231 
232     Register getRegisterByName(const char* RegName, EVT VT,
233                                const MachineFunction &MF) const override;
234 
235     /// If a physical register, this returns the register that receives the
236     /// exception address on entry to an EH pad.
237     unsigned
238     getExceptionPointerRegister(const Constant *PersonalityFn) const override {
239       return Hexagon::R0;
240     }
241 
242     /// If a physical register, this returns the register that receives the
243     /// exception typeid on entry to a landing pad.
244     unsigned
245     getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
246       return Hexagon::R1;
247     }
248 
249     SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
250     SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
251     SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
252 
253     EVT getSetCCResultType(const DataLayout &, LLVMContext &C,
254                            EVT VT) const override {
255       if (!VT.isVector())
256         return MVT::i1;
257       else
258         return EVT::getVectorVT(C, MVT::i1, VT.getVectorNumElements());
259     }
260 
261     bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
262                                     SDValue &Base, SDValue &Offset,
263                                     ISD::MemIndexedMode &AM,
264                                     SelectionDAG &DAG) const override;
265 
266     ConstraintType getConstraintType(StringRef Constraint) const override;
267 
268     std::pair<unsigned, const TargetRegisterClass *>
269     getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
270                                  StringRef Constraint, MVT VT) const override;
271 
272     unsigned
273     getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
274       if (ConstraintCode == "o")
275         return InlineAsm::Constraint_o;
276       return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
277     }
278 
279     // Intrinsics
280     SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
281     SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;
282     /// isLegalAddressingMode - Return true if the addressing mode represented
283     /// by AM is legal for this target, for a load/store of the specified type.
284     /// The type may be VoidTy, in which case only return true if the addressing
285     /// mode is legal for a load/store of any legal type.
286     /// TODO: Handle pre/postinc as well.
287     bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
288                                Type *Ty, unsigned AS,
289                                Instruction *I = nullptr) const override;
290     /// Return true if folding a constant offset with the given GlobalAddress
291     /// is legal.  It is frequently not legal in PIC relocation models.
292     bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
293 
294     bool isFPImmLegal(const APFloat &Imm, EVT VT,
295                       bool ForCodeSize) const override;
296 
297     /// isLegalICmpImmediate - Return true if the specified immediate is legal
298     /// icmp immediate, that is the target has icmp instructions which can
299     /// compare a register against the immediate without having to materialize
300     /// the immediate into a register.
301     bool isLegalICmpImmediate(int64_t Imm) const override;
302 
303     EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
304         unsigned SrcAlign, bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc,
305         const AttributeList &FuncAttributes) const override;
306 
307     bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace,
308         unsigned Align, MachineMemOperand::Flags Flags, bool *Fast)
309         const override;
310 
311     /// Returns relocation base for the given PIC jumptable.
312     SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG)
313                                      const override;
314 
315     bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy,
316                                EVT NewVT) const override;
317 
318     // Handling of atomic RMW instructions.
319     Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr,
320         AtomicOrdering Ord) const override;
321     Value *emitStoreConditional(IRBuilder<> &Builder, Value *Val,
322         Value *Addr, AtomicOrdering Ord) const override;
323     AtomicExpansionKind shouldExpandAtomicLoadInIR(LoadInst *LI) const override;
324     bool shouldExpandAtomicStoreInIR(StoreInst *SI) const override;
325     AtomicExpansionKind
326     shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override;
327 
328     AtomicExpansionKind
329     shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override {
330       return AtomicExpansionKind::LLSC;
331     }
332 
333   private:
334     void initializeHVXLowering();
335     void validateConstPtrAlignment(SDValue Ptr, const SDLoc &dl,
336                                    unsigned NeedAlign) const;
337 
338     std::pair<SDValue,int> getBaseAndOffset(SDValue Addr) const;
339 
340     bool getBuildVectorConstInts(ArrayRef<SDValue> Values, MVT VecTy,
341                                  SelectionDAG &DAG,
342                                  MutableArrayRef<ConstantInt*> Consts) const;
343     SDValue buildVector32(ArrayRef<SDValue> Elem, const SDLoc &dl, MVT VecTy,
344                           SelectionDAG &DAG) const;
345     SDValue buildVector64(ArrayRef<SDValue> Elem, const SDLoc &dl, MVT VecTy,
346                           SelectionDAG &DAG) const;
347     SDValue extractVector(SDValue VecV, SDValue IdxV, const SDLoc &dl,
348                           MVT ValTy, MVT ResTy, SelectionDAG &DAG) const;
349     SDValue insertVector(SDValue VecV, SDValue ValV, SDValue IdxV,
350                          const SDLoc &dl, MVT ValTy, SelectionDAG &DAG) const;
351     SDValue expandPredicate(SDValue Vec32, const SDLoc &dl,
352                             SelectionDAG &DAG) const;
353     SDValue contractPredicate(SDValue Vec64, const SDLoc &dl,
354                               SelectionDAG &DAG) const;
355     SDValue getVectorShiftByInt(SDValue Op, SelectionDAG &DAG) const;
356 
357     bool isUndef(SDValue Op) const {
358       if (Op.isMachineOpcode())
359         return Op.getMachineOpcode() == TargetOpcode::IMPLICIT_DEF;
360       return Op.getOpcode() == ISD::UNDEF;
361     }
362     SDValue getInstr(unsigned MachineOpc, const SDLoc &dl, MVT Ty,
363                      ArrayRef<SDValue> Ops, SelectionDAG &DAG) const {
364       SDNode *N = DAG.getMachineNode(MachineOpc, dl, Ty, Ops);
365       return SDValue(N, 0);
366     }
367     SDValue getZero(const SDLoc &dl, MVT Ty, SelectionDAG &DAG) const;
368 
369     using VectorPair = std::pair<SDValue, SDValue>;
370     using TypePair = std::pair<MVT, MVT>;
371 
372     SDValue getInt(unsigned IntId, MVT ResTy, ArrayRef<SDValue> Ops,
373                    const SDLoc &dl, SelectionDAG &DAG) const;
374 
375     MVT ty(SDValue Op) const {
376       return Op.getValueType().getSimpleVT();
377     }
378     TypePair ty(const VectorPair &Ops) const {
379       return { Ops.first.getValueType().getSimpleVT(),
380                Ops.second.getValueType().getSimpleVT() };
381     }
382     MVT tyScalar(MVT Ty) const {
383       if (!Ty.isVector())
384         return Ty;
385       return MVT::getIntegerVT(Ty.getSizeInBits());
386     }
387     MVT tyVector(MVT Ty, MVT ElemTy) const {
388       if (Ty.isVector() && Ty.getVectorElementType() == ElemTy)
389         return Ty;
390       unsigned TyWidth = Ty.getSizeInBits();
391       unsigned ElemWidth = ElemTy.getSizeInBits();
392       assert((TyWidth % ElemWidth) == 0);
393       return MVT::getVectorVT(ElemTy, TyWidth/ElemWidth);
394     }
395 
396     MVT typeJoin(const TypePair &Tys) const;
397     TypePair typeSplit(MVT Ty) const;
398     MVT typeExtElem(MVT VecTy, unsigned Factor) const;
399     MVT typeTruncElem(MVT VecTy, unsigned Factor) const;
400 
401     SDValue opJoin(const VectorPair &Ops, const SDLoc &dl,
402                    SelectionDAG &DAG) const;
403     VectorPair opSplit(SDValue Vec, const SDLoc &dl, SelectionDAG &DAG) const;
404     SDValue opCastElem(SDValue Vec, MVT ElemTy, SelectionDAG &DAG) const;
405 
406     bool isHvxSingleTy(MVT Ty) const;
407     bool isHvxPairTy(MVT Ty) const;
408     SDValue convertToByteIndex(SDValue ElemIdx, MVT ElemTy,
409                                SelectionDAG &DAG) const;
410     SDValue getIndexInWord32(SDValue Idx, MVT ElemTy, SelectionDAG &DAG) const;
411     SDValue getByteShuffle(const SDLoc &dl, SDValue Op0, SDValue Op1,
412                            ArrayRef<int> Mask, SelectionDAG &DAG) const;
413 
414     SDValue buildHvxVectorReg(ArrayRef<SDValue> Values, const SDLoc &dl,
415                               MVT VecTy, SelectionDAG &DAG) const;
416     SDValue buildHvxVectorPred(ArrayRef<SDValue> Values, const SDLoc &dl,
417                                MVT VecTy, SelectionDAG &DAG) const;
418     SDValue createHvxPrefixPred(SDValue PredV, const SDLoc &dl,
419                                 unsigned BitBytes, bool ZeroFill,
420                                 SelectionDAG &DAG) const;
421     SDValue extractHvxElementReg(SDValue VecV, SDValue IdxV, const SDLoc &dl,
422                                  MVT ResTy, SelectionDAG &DAG) const;
423     SDValue extractHvxElementPred(SDValue VecV, SDValue IdxV, const SDLoc &dl,
424                                   MVT ResTy, SelectionDAG &DAG) const;
425     SDValue insertHvxElementReg(SDValue VecV, SDValue IdxV, SDValue ValV,
426                                 const SDLoc &dl, SelectionDAG &DAG) const;
427     SDValue insertHvxElementPred(SDValue VecV, SDValue IdxV, SDValue ValV,
428                                  const SDLoc &dl, SelectionDAG &DAG) const;
429     SDValue extractHvxSubvectorReg(SDValue VecV, SDValue IdxV, const SDLoc &dl,
430                                    MVT ResTy, SelectionDAG &DAG) const;
431     SDValue extractHvxSubvectorPred(SDValue VecV, SDValue IdxV, const SDLoc &dl,
432                                     MVT ResTy, SelectionDAG &DAG) const;
433     SDValue insertHvxSubvectorReg(SDValue VecV, SDValue SubV, SDValue IdxV,
434                                   const SDLoc &dl, SelectionDAG &DAG) const;
435     SDValue insertHvxSubvectorPred(SDValue VecV, SDValue SubV, SDValue IdxV,
436                                    const SDLoc &dl, SelectionDAG &DAG) const;
437     SDValue extendHvxVectorPred(SDValue VecV, const SDLoc &dl, MVT ResTy,
438                                 bool ZeroExt, SelectionDAG &DAG) const;
439 
440     SDValue LowerHvxBuildVector(SDValue Op, SelectionDAG &DAG) const;
441     SDValue LowerHvxConcatVectors(SDValue Op, SelectionDAG &DAG) const;
442     SDValue LowerHvxExtractElement(SDValue Op, SelectionDAG &DAG) const;
443     SDValue LowerHvxInsertElement(SDValue Op, SelectionDAG &DAG) const;
444     SDValue LowerHvxExtractSubvector(SDValue Op, SelectionDAG &DAG) const;
445     SDValue LowerHvxInsertSubvector(SDValue Op, SelectionDAG &DAG) const;
446 
447     SDValue LowerHvxAnyExt(SDValue Op, SelectionDAG &DAG) const;
448     SDValue LowerHvxSignExt(SDValue Op, SelectionDAG &DAG) const;
449     SDValue LowerHvxZeroExt(SDValue Op, SelectionDAG &DAG) const;
450     SDValue LowerHvxCttz(SDValue Op, SelectionDAG &DAG) const;
451     SDValue LowerHvxMul(SDValue Op, SelectionDAG &DAG) const;
452     SDValue LowerHvxMulh(SDValue Op, SelectionDAG &DAG) const;
453     SDValue LowerHvxSetCC(SDValue Op, SelectionDAG &DAG) const;
454     SDValue LowerHvxExtend(SDValue Op, SelectionDAG &DAG) const;
455     SDValue LowerHvxShift(SDValue Op, SelectionDAG &DAG) const;
456 
457     SDValue SplitHvxPairOp(SDValue Op, SelectionDAG &DAG) const;
458     SDValue SplitHvxMemOp(SDValue Op, SelectionDAG &DAG) const;
459 
460     std::pair<const TargetRegisterClass*, uint8_t>
461     findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT)
462         const override;
463 
464     bool isHvxOperation(SDValue Op) const;
465     SDValue LowerHvxOperation(SDValue Op, SelectionDAG &DAG) const;
466 
467     SDValue PerformHvxDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
468   };
469 
470 } // end namespace llvm
471 
472 #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
473