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