xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/Hexagon/HexagonISelLowering.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- HexagonISelLowering.h - Hexagon DAG Lowering Interface --*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines the interfaces that Hexagon uses to lower LLVM code into a
100b57cec5SDimitry Andric // selection DAG.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
150b57cec5SDimitry Andric #define LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #include "Hexagon.h"
18e8d8bef9SDimitry Andric #include "MCTargetDesc/HexagonMCTargetDesc.h"
190b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
200b57cec5SDimitry Andric #include "llvm/CodeGen/ISDOpcodes.h"
210b57cec5SDimitry Andric #include "llvm/CodeGen/SelectionDAGNodes.h"
220b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLowering.h"
230b57cec5SDimitry Andric #include "llvm/CodeGen/ValueTypes.h"
24*0fca6ea1SDimitry Andric #include "llvm/CodeGenTypes/MachineValueType.h"
250b57cec5SDimitry Andric #include "llvm/IR/CallingConv.h"
260b57cec5SDimitry Andric #include "llvm/IR/InlineAsm.h"
270b57cec5SDimitry Andric #include <cstdint>
280b57cec5SDimitry Andric #include <utility>
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric namespace llvm {
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric namespace HexagonISD {
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric enum NodeType : unsigned {
350b57cec5SDimitry Andric   OP_BEGIN = ISD::BUILTIN_OP_END,
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric   CONST32 = OP_BEGIN,
380b57cec5SDimitry Andric   CONST32_GP,  // For marking data present in GP.
390b57cec5SDimitry Andric   ADDC,        // Add with carry: (X, Y, Cin) -> (X+Y, Cout).
400b57cec5SDimitry Andric   SUBC,        // Sub with carry: (X, Y, Cin) -> (X+~Y+Cin, Cout).
410b57cec5SDimitry Andric   ALLOCA,
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric   AT_GOT,      // Index in GOT.
440b57cec5SDimitry Andric   AT_PCREL,    // Offset relative to PC.
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric   CALL,        // Function call.
470b57cec5SDimitry Andric   CALLnr,      // Function call that does not return.
480b57cec5SDimitry Andric   CALLR,
490b57cec5SDimitry Andric 
5006c3fb27SDimitry Andric   RET_GLUE,    // Return with a glue operand.
510b57cec5SDimitry Andric   BARRIER,     // Memory barrier.
520b57cec5SDimitry Andric   JT,          // Jump table.
530b57cec5SDimitry Andric   CP,          // Constant pool.
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric   COMBINE,
56bdd1243dSDimitry Andric   VASL,        // Vector shifts by a scalar value
570b57cec5SDimitry Andric   VASR,
580b57cec5SDimitry Andric   VLSR,
59bdd1243dSDimitry Andric   MFSHL,       // Funnel shifts with the shift amount guaranteed to be
60bdd1243dSDimitry Andric   MFSHR,       // within the range of the bit width of the element.
61bdd1243dSDimitry Andric 
62bdd1243dSDimitry Andric   SSAT,        // Signed saturate.
63bdd1243dSDimitry Andric   USAT,        // Unsigned saturate.
64bdd1243dSDimitry Andric   SMUL_LOHI,   // Same as ISD::SMUL_LOHI, but opaque to the combiner.
65bdd1243dSDimitry Andric   UMUL_LOHI,   // Same as ISD::UMUL_LOHI, but opaque to the combiner.
66bdd1243dSDimitry Andric                // We want to legalize MULH[SU] to [SU]MUL_LOHI, but the
67bdd1243dSDimitry Andric                // combiner will keep rewriting it back to MULH[SU].
68bdd1243dSDimitry Andric   USMUL_LOHI,  // Like SMUL_LOHI, but unsigned*signed.
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric   TSTBIT,
710b57cec5SDimitry Andric   INSERT,
720b57cec5SDimitry Andric   EXTRACTU,
730b57cec5SDimitry Andric   VEXTRACTW,
740b57cec5SDimitry Andric   VINSERTW0,
750b57cec5SDimitry Andric   VROR,
760b57cec5SDimitry Andric   TC_RETURN,
770b57cec5SDimitry Andric   EH_RETURN,
780b57cec5SDimitry Andric   DCFETCH,
790b57cec5SDimitry Andric   READCYCLE,
80*0fca6ea1SDimitry Andric   READTIMER,
818bcb0991SDimitry Andric   PTRUE,
828bcb0991SDimitry Andric   PFALSE,
830b57cec5SDimitry Andric   D2P,         // Convert 8-byte value to 8-bit predicate register. [*]
840b57cec5SDimitry Andric   P2D,         // Convert 8-bit predicate register to 8-byte value. [*]
850b57cec5SDimitry Andric   V2Q,         // Convert HVX vector to a vector predicate reg. [*]
860b57cec5SDimitry Andric   Q2V,         // Convert vector predicate to an HVX vector. [*]
870b57cec5SDimitry Andric                // [*] The equivalence is defined as "Q <=> (V != 0)",
880b57cec5SDimitry Andric                //     where the != operation compares bytes.
890b57cec5SDimitry Andric                // Note: V != 0 is implemented as V >u 0.
900b57cec5SDimitry Andric   QCAT,
910b57cec5SDimitry Andric   QTRUE,
920b57cec5SDimitry Andric   QFALSE,
93bdd1243dSDimitry Andric 
94bdd1243dSDimitry Andric   TL_EXTEND,   // Wrappers for ISD::*_EXTEND and ISD::TRUNCATE to prevent DAG
95bdd1243dSDimitry Andric   TL_TRUNCATE, // from auto-folding operations, e.g.
96bdd1243dSDimitry Andric                // (i32 ext (i16 ext i8)) would be folded to (i32 ext i8).
97bdd1243dSDimitry Andric                // To simplify the type legalization, we want to keep these
98bdd1243dSDimitry Andric                // single steps separate during type legalization.
99bdd1243dSDimitry Andric                // TL_[EXTEND|TRUNCATE] Inp, i128 _, i32 Opc
100bdd1243dSDimitry Andric                // * Inp is the original input to extend/truncate,
101bdd1243dSDimitry Andric                // * _ is a dummy operand with an illegal type (can be undef),
102bdd1243dSDimitry Andric                // * Opc is the original opcode.
103bdd1243dSDimitry Andric                // The legalization process (in Hexagon lowering code) will
104bdd1243dSDimitry Andric                // first deal with the "real" types (i.e. Inp and the result),
105bdd1243dSDimitry Andric                // and once all of them are processed, the wrapper node will
106bdd1243dSDimitry Andric                // be replaced with the original ISD node. The dummy illegal
107bdd1243dSDimitry Andric                // operand is there to make sure that the legalization hooks
108bdd1243dSDimitry Andric                // are called again after everything else is legal, giving
109bdd1243dSDimitry Andric                // us the opportunity to undo the wrapping.
110bdd1243dSDimitry Andric 
1110b57cec5SDimitry Andric   TYPECAST,    // No-op that's used to convert between different legal
1120b57cec5SDimitry Andric                // types in a register.
1130b57cec5SDimitry Andric   VALIGN,      // Align two vectors (in Op0, Op1) to one that would have
1140b57cec5SDimitry Andric                // been loaded from address in Op2.
1150b57cec5SDimitry Andric   VALIGNADDR,  // Align vector address: Op0 & -Op1, except when it is
1160b57cec5SDimitry Andric                // an address in a vector load, then it's a no-op.
117e8d8bef9SDimitry Andric   ISEL,        // Marker for nodes that were created during ISel, and
118e8d8bef9SDimitry Andric                // which need explicit selection (would have been left
119e8d8bef9SDimitry Andric                // unselected otherwise).
1200b57cec5SDimitry Andric   OP_END
1210b57cec5SDimitry Andric };
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric } // end namespace HexagonISD
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric class HexagonSubtarget;
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric class HexagonTargetLowering : public TargetLowering {
1280b57cec5SDimitry Andric   int VarArgsFrameOffset;   // Frame offset to start of varargs area.
1290b57cec5SDimitry Andric   const HexagonTargetMachine &HTM;
1300b57cec5SDimitry Andric   const HexagonSubtarget &Subtarget;
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric public:
1330b57cec5SDimitry Andric   explicit HexagonTargetLowering(const TargetMachine &TM,
1340b57cec5SDimitry Andric                                  const HexagonSubtarget &ST);
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric   /// IsEligibleForTailCallOptimization - Check whether the call is eligible
1370b57cec5SDimitry Andric   /// for tail call optimization. Targets which want to do tail call
1380b57cec5SDimitry Andric   /// optimization should implement this function.
1390b57cec5SDimitry Andric   bool IsEligibleForTailCallOptimization(SDValue Callee,
1400b57cec5SDimitry Andric       CallingConv::ID CalleeCC, bool isVarArg, bool isCalleeStructRet,
1410b57cec5SDimitry Andric       bool isCallerStructRet, const SmallVectorImpl<ISD::OutputArg> &Outs,
1420b57cec5SDimitry Andric       const SmallVectorImpl<SDValue> &OutVals,
1430b57cec5SDimitry Andric       const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG& DAG) const;
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric   bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I,
1460b57cec5SDimitry Andric                           MachineFunction &MF,
1470b57cec5SDimitry Andric                           unsigned Intrinsic) const override;
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric   bool isTruncateFree(Type *Ty1, Type *Ty2) const override;
1500b57cec5SDimitry Andric   bool isTruncateFree(EVT VT1, EVT VT2) const override;
1510b57cec5SDimitry Andric 
152bdd1243dSDimitry Andric   bool isCheapToSpeculateCttz(Type *) const override { return true; }
153bdd1243dSDimitry Andric   bool isCheapToSpeculateCtlz(Type *) const override { return true; }
1540b57cec5SDimitry Andric   bool isCtlzFast() const override { return true; }
1550b57cec5SDimitry Andric 
1568bcb0991SDimitry Andric   bool hasBitTest(SDValue X, SDValue Y) const override;
1578bcb0991SDimitry Andric 
1580b57cec5SDimitry Andric   bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override;
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric   /// Return true if an FMA operation is faster than a pair of mul and add
1610b57cec5SDimitry Andric   /// instructions. fmuladd intrinsics will be expanded to FMAs when this
1620b57cec5SDimitry Andric   /// method returns true (and FMAs are legal), otherwise fmuladd is
1630b57cec5SDimitry Andric   /// expanded to mul + add.
164480093f4SDimitry Andric   bool isFMAFasterThanFMulAndFAdd(const MachineFunction &,
165480093f4SDimitry Andric                                   EVT) const override;
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric   // Should we expand the build vector with shuffles?
1680b57cec5SDimitry Andric   bool shouldExpandBuildVectorWithShuffles(EVT VT,
1690b57cec5SDimitry Andric       unsigned DefinedValues) const override;
170bdd1243dSDimitry Andric   bool isExtractSubvectorCheap(EVT ResVT, EVT SrcVT,
171bdd1243dSDimitry Andric       unsigned Index) const override;
172bdd1243dSDimitry Andric 
173bdd1243dSDimitry Andric   bool isTargetCanonicalConstantNode(SDValue Op) const override;
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric   bool isShuffleMaskLegal(ArrayRef<int> Mask, EVT VT) const override;
176bdd1243dSDimitry Andric   LegalizeTypeAction getPreferredVectorAction(MVT VT) const override;
177bdd1243dSDimitry Andric   LegalizeAction getCustomOperationAction(SDNode &Op) const override;
1780b57cec5SDimitry Andric 
1790b57cec5SDimitry Andric   SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
1800b57cec5SDimitry Andric   void LowerOperationWrapper(SDNode *N, SmallVectorImpl<SDValue> &Results,
1810b57cec5SDimitry Andric                              SelectionDAG &DAG) const override;
1820b57cec5SDimitry Andric   void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
1830b57cec5SDimitry Andric                           SelectionDAG &DAG) const override;
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric   const char *getTargetNodeName(unsigned Opcode) const override;
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric   SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
1880b57cec5SDimitry Andric   SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;
1890b57cec5SDimitry Andric   SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
1900b57cec5SDimitry Andric   SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
1910b57cec5SDimitry Andric   SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
1920b57cec5SDimitry Andric   SDValue LowerINSERT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
1930b57cec5SDimitry Andric   SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
1940b57cec5SDimitry Andric   SDValue LowerVECTOR_SHIFT(SDValue Op, SelectionDAG &DAG) const;
1950b57cec5SDimitry Andric   SDValue LowerROTL(SDValue Op, SelectionDAG &DAG) const;
1960b57cec5SDimitry Andric   SDValue LowerBITCAST(SDValue Op, SelectionDAG &DAG) const;
1970b57cec5SDimitry Andric   SDValue LowerANY_EXTEND(SDValue Op, SelectionDAG &DAG) const;
1980b57cec5SDimitry Andric   SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) const;
1990b57cec5SDimitry Andric   SDValue LowerZERO_EXTEND(SDValue Op, SelectionDAG &DAG) const;
2000b57cec5SDimitry Andric   SDValue LowerLoad(SDValue Op, SelectionDAG &DAG) const;
2010b57cec5SDimitry Andric   SDValue LowerStore(SDValue Op, SelectionDAG &DAG) const;
2020b57cec5SDimitry Andric   SDValue LowerUnalignedLoad(SDValue Op, SelectionDAG &DAG) const;
2030b57cec5SDimitry Andric   SDValue LowerUAddSubO(SDValue Op, SelectionDAG &DAG) const;
20406c3fb27SDimitry Andric   SDValue LowerUAddSubOCarry(SDValue Op, SelectionDAG &DAG) const;
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric   SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
2070b57cec5SDimitry Andric   SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
208*0fca6ea1SDimitry Andric   SDValue LowerFDIV(SDValue Op, SelectionDAG &DAG) const;
2090b57cec5SDimitry Andric   SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;
2100b57cec5SDimitry Andric   SDValue LowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const;
211*0fca6ea1SDimitry Andric   SDValue LowerREADSTEADYCOUNTER(SDValue Op, SelectionDAG &DAG) const;
2120b57cec5SDimitry Andric   SDValue LowerEH_LABEL(SDValue Op, SelectionDAG &DAG) const;
2130b57cec5SDimitry Andric   SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
2140b57cec5SDimitry Andric   SDValue
2150b57cec5SDimitry Andric   LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
2160b57cec5SDimitry Andric                        const SmallVectorImpl<ISD::InputArg> &Ins,
2170b57cec5SDimitry Andric                        const SDLoc &dl, SelectionDAG &DAG,
2180b57cec5SDimitry Andric                        SmallVectorImpl<SDValue> &InVals) const override;
2190b57cec5SDimitry Andric   SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const;
2200b57cec5SDimitry Andric   SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
2210b57cec5SDimitry Andric   SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
2220b57cec5SDimitry Andric   SDValue LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
2230b57cec5SDimitry Andric       SelectionDAG &DAG) const;
2240b57cec5SDimitry Andric   SDValue LowerToTLSInitialExecModel(GlobalAddressSDNode *GA,
2250b57cec5SDimitry Andric       SelectionDAG &DAG) const;
2260b57cec5SDimitry Andric   SDValue LowerToTLSLocalExecModel(GlobalAddressSDNode *GA,
2270b57cec5SDimitry Andric       SelectionDAG &DAG) const;
2280b57cec5SDimitry Andric   SDValue GetDynamicTLSAddr(SelectionDAG &DAG, SDValue Chain,
22906c3fb27SDimitry Andric       GlobalAddressSDNode *GA, SDValue InGlue, EVT PtrVT,
23006c3fb27SDimitry Andric       unsigned ReturnReg, unsigned char OperandGlues) const;
2310b57cec5SDimitry Andric   SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG) const;
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric   SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
2340b57cec5SDimitry Andric       SmallVectorImpl<SDValue> &InVals) const override;
23506c3fb27SDimitry Andric   SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
2360b57cec5SDimitry Andric                           CallingConv::ID CallConv, bool isVarArg,
2370b57cec5SDimitry Andric                           const SmallVectorImpl<ISD::InputArg> &Ins,
2380b57cec5SDimitry Andric                           const SDLoc &dl, SelectionDAG &DAG,
2390b57cec5SDimitry Andric                           SmallVectorImpl<SDValue> &InVals,
2400b57cec5SDimitry Andric                           const SmallVectorImpl<SDValue> &OutVals,
2410b57cec5SDimitry Andric                           SDValue Callee) const;
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric   SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
2440b57cec5SDimitry Andric   SDValue LowerVSELECT(SDValue Op, SelectionDAG &DAG) const;
2450b57cec5SDimitry Andric   SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
2460b57cec5SDimitry Andric   SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
2470b57cec5SDimitry Andric   SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
2480b57cec5SDimitry Andric 
2490b57cec5SDimitry Andric   bool CanLowerReturn(CallingConv::ID CallConv,
2500b57cec5SDimitry Andric                       MachineFunction &MF, bool isVarArg,
2510b57cec5SDimitry Andric                       const SmallVectorImpl<ISD::OutputArg> &Outs,
2520b57cec5SDimitry Andric                       LLVMContext &Context) const override;
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric   SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
2550b57cec5SDimitry Andric                       const SmallVectorImpl<ISD::OutputArg> &Outs,
2560b57cec5SDimitry Andric                       const SmallVectorImpl<SDValue> &OutVals,
2570b57cec5SDimitry Andric                       const SDLoc &dl, SelectionDAG &DAG) const override;
2580b57cec5SDimitry Andric 
2598bcb0991SDimitry Andric   SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
2608bcb0991SDimitry Andric 
2610b57cec5SDimitry Andric   bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
2620b57cec5SDimitry Andric 
263480093f4SDimitry Andric   Register getRegisterByName(const char* RegName, LLT VT,
2648bcb0991SDimitry Andric                              const MachineFunction &MF) const override;
2650b57cec5SDimitry Andric 
2660b57cec5SDimitry Andric   /// If a physical register, this returns the register that receives the
2670b57cec5SDimitry Andric   /// exception address on entry to an EH pad.
2685ffd83dbSDimitry Andric   Register
2690b57cec5SDimitry Andric   getExceptionPointerRegister(const Constant *PersonalityFn) const override {
2700b57cec5SDimitry Andric     return Hexagon::R0;
2710b57cec5SDimitry Andric   }
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric   /// If a physical register, this returns the register that receives the
2740b57cec5SDimitry Andric   /// exception typeid on entry to a landing pad.
2755ffd83dbSDimitry Andric   Register
2760b57cec5SDimitry Andric   getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
2770b57cec5SDimitry Andric     return Hexagon::R1;
2780b57cec5SDimitry Andric   }
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric   SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
2815ffd83dbSDimitry Andric   SDValue LowerVACOPY(SDValue Op, SelectionDAG &DAG) const;
2820b57cec5SDimitry Andric   SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
2830b57cec5SDimitry Andric   SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric   EVT getSetCCResultType(const DataLayout &, LLVMContext &C,
2860b57cec5SDimitry Andric                          EVT VT) const override {
2870b57cec5SDimitry Andric     if (!VT.isVector())
2880b57cec5SDimitry Andric       return MVT::i1;
2890b57cec5SDimitry Andric     else
2900b57cec5SDimitry Andric       return EVT::getVectorVT(C, MVT::i1, VT.getVectorNumElements());
2910b57cec5SDimitry Andric   }
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric   bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
2940b57cec5SDimitry Andric                                   SDValue &Base, SDValue &Offset,
2950b57cec5SDimitry Andric                                   ISD::MemIndexedMode &AM,
2960b57cec5SDimitry Andric                                   SelectionDAG &DAG) const override;
2970b57cec5SDimitry Andric 
2980b57cec5SDimitry Andric   ConstraintType getConstraintType(StringRef Constraint) const override;
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   std::pair<unsigned, const TargetRegisterClass *>
3010b57cec5SDimitry Andric   getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
3020b57cec5SDimitry Andric                                StringRef Constraint, MVT VT) const override;
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric   // Intrinsics
3050b57cec5SDimitry Andric   SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
3060b57cec5SDimitry Andric   SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;
3070b57cec5SDimitry Andric   /// isLegalAddressingMode - Return true if the addressing mode represented
3080b57cec5SDimitry Andric   /// by AM is legal for this target, for a load/store of the specified type.
3090b57cec5SDimitry Andric   /// The type may be VoidTy, in which case only return true if the addressing
3100b57cec5SDimitry Andric   /// mode is legal for a load/store of any legal type.
3110b57cec5SDimitry Andric   /// TODO: Handle pre/postinc as well.
3120b57cec5SDimitry Andric   bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
3130b57cec5SDimitry Andric                              Type *Ty, unsigned AS,
3140b57cec5SDimitry Andric                              Instruction *I = nullptr) const override;
3150b57cec5SDimitry Andric   /// Return true if folding a constant offset with the given GlobalAddress
3160b57cec5SDimitry Andric   /// is legal.  It is frequently not legal in PIC relocation models.
3170b57cec5SDimitry Andric   bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
3180b57cec5SDimitry Andric 
3190b57cec5SDimitry Andric   bool isFPImmLegal(const APFloat &Imm, EVT VT,
3200b57cec5SDimitry Andric                     bool ForCodeSize) const override;
3210b57cec5SDimitry Andric 
3220b57cec5SDimitry Andric   /// isLegalICmpImmediate - Return true if the specified immediate is legal
3230b57cec5SDimitry Andric   /// icmp immediate, that is the target has icmp instructions which can
3240b57cec5SDimitry Andric   /// compare a register against the immediate without having to materialize
3250b57cec5SDimitry Andric   /// the immediate into a register.
3260b57cec5SDimitry Andric   bool isLegalICmpImmediate(int64_t Imm) const override;
3270b57cec5SDimitry Andric 
3285ffd83dbSDimitry Andric   EVT getOptimalMemOpType(const MemOp &Op,
3290b57cec5SDimitry Andric                           const AttributeList &FuncAttributes) const override;
3300b57cec5SDimitry Andric 
3315ffd83dbSDimitry Andric   bool allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, EVT VT,
3325ffd83dbSDimitry Andric                           unsigned AddrSpace, Align Alignment,
3335ffd83dbSDimitry Andric                           MachineMemOperand::Flags Flags,
334bdd1243dSDimitry Andric                           unsigned *Fast) const override;
3355ffd83dbSDimitry Andric 
3360b57cec5SDimitry Andric   bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace,
337fe6060f1SDimitry Andric                                       Align Alignment,
338fe6060f1SDimitry Andric                                       MachineMemOperand::Flags Flags,
339bdd1243dSDimitry Andric                                       unsigned *Fast) const override;
3400b57cec5SDimitry Andric 
3410b57cec5SDimitry Andric   /// Returns relocation base for the given PIC jumptable.
3420b57cec5SDimitry Andric   SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG)
3430b57cec5SDimitry Andric                                    const override;
3440b57cec5SDimitry Andric 
3450b57cec5SDimitry Andric   bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy,
3460b57cec5SDimitry Andric                              EVT NewVT) const override;
3470b57cec5SDimitry Andric 
348bdd1243dSDimitry Andric   void AdjustInstrPostInstrSelection(MachineInstr &MI,
349bdd1243dSDimitry Andric                                      SDNode *Node) const override;
350bdd1243dSDimitry Andric 
3510b57cec5SDimitry Andric   // Handling of atomic RMW instructions.
352fe6060f1SDimitry Andric   Value *emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr,
3530b57cec5SDimitry Andric                         AtomicOrdering Ord) const override;
354fe6060f1SDimitry Andric   Value *emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr,
355fe6060f1SDimitry Andric                               AtomicOrdering Ord) const override;
3560b57cec5SDimitry Andric   AtomicExpansionKind shouldExpandAtomicLoadInIR(LoadInst *LI) const override;
35781ad6265SDimitry Andric   AtomicExpansionKind shouldExpandAtomicStoreInIR(StoreInst *SI) const override;
3580b57cec5SDimitry Andric   AtomicExpansionKind
3590b57cec5SDimitry Andric   shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override;
3600b57cec5SDimitry Andric 
3610b57cec5SDimitry Andric   AtomicExpansionKind
3620b57cec5SDimitry Andric   shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override {
3630b57cec5SDimitry Andric     return AtomicExpansionKind::LLSC;
3640b57cec5SDimitry Andric   }
3650b57cec5SDimitry Andric 
3660b57cec5SDimitry Andric private:
3670b57cec5SDimitry Andric   void initializeHVXLowering();
368e8d8bef9SDimitry Andric   unsigned getPreferredHvxVectorAction(MVT VecTy) const;
369bdd1243dSDimitry Andric   unsigned getCustomHvxOperationAction(SDNode &Op) const;
370e8d8bef9SDimitry Andric 
371fe6060f1SDimitry Andric   bool validateConstPtrAlignment(SDValue Ptr, Align NeedAlign, const SDLoc &dl,
372fe6060f1SDimitry Andric                                  SelectionDAG &DAG) const;
373fe6060f1SDimitry Andric   SDValue replaceMemWithUndef(SDValue Op, SelectionDAG &DAG) const;
3740b57cec5SDimitry Andric 
3750b57cec5SDimitry Andric   std::pair<SDValue,int> getBaseAndOffset(SDValue Addr) const;
3760b57cec5SDimitry Andric 
3770b57cec5SDimitry Andric   bool getBuildVectorConstInts(ArrayRef<SDValue> Values, MVT VecTy,
3780b57cec5SDimitry Andric                                SelectionDAG &DAG,
3790b57cec5SDimitry Andric                                MutableArrayRef<ConstantInt*> Consts) const;
3800b57cec5SDimitry Andric   SDValue buildVector32(ArrayRef<SDValue> Elem, const SDLoc &dl, MVT VecTy,
3810b57cec5SDimitry Andric                         SelectionDAG &DAG) const;
3820b57cec5SDimitry Andric   SDValue buildVector64(ArrayRef<SDValue> Elem, const SDLoc &dl, MVT VecTy,
3830b57cec5SDimitry Andric                         SelectionDAG &DAG) const;
3840b57cec5SDimitry Andric   SDValue extractVector(SDValue VecV, SDValue IdxV, const SDLoc &dl,
3850b57cec5SDimitry Andric                         MVT ValTy, MVT ResTy, SelectionDAG &DAG) const;
386bdd1243dSDimitry Andric   SDValue extractVectorPred(SDValue VecV, SDValue IdxV, const SDLoc &dl,
387bdd1243dSDimitry Andric                             MVT ValTy, MVT ResTy, SelectionDAG &DAG) const;
3880b57cec5SDimitry Andric   SDValue insertVector(SDValue VecV, SDValue ValV, SDValue IdxV,
3890b57cec5SDimitry Andric                        const SDLoc &dl, MVT ValTy, SelectionDAG &DAG) const;
390bdd1243dSDimitry Andric   SDValue insertVectorPred(SDValue VecV, SDValue ValV, SDValue IdxV,
391bdd1243dSDimitry Andric                            const SDLoc &dl, MVT ValTy, SelectionDAG &DAG) const;
3920b57cec5SDimitry Andric   SDValue expandPredicate(SDValue Vec32, const SDLoc &dl,
3930b57cec5SDimitry Andric                           SelectionDAG &DAG) const;
3940b57cec5SDimitry Andric   SDValue contractPredicate(SDValue Vec64, const SDLoc &dl,
3950b57cec5SDimitry Andric                             SelectionDAG &DAG) const;
396bdd1243dSDimitry Andric   SDValue getSplatValue(SDValue Op, SelectionDAG &DAG) const;
3970b57cec5SDimitry Andric   SDValue getVectorShiftByInt(SDValue Op, SelectionDAG &DAG) const;
398e8d8bef9SDimitry Andric   SDValue appendUndef(SDValue Val, MVT ResTy, SelectionDAG &DAG) const;
399bdd1243dSDimitry Andric   SDValue getCombine(SDValue Hi, SDValue Lo, const SDLoc &dl, MVT ResTy,
400bdd1243dSDimitry Andric                      SelectionDAG &DAG) const;
4010b57cec5SDimitry Andric 
4020b57cec5SDimitry Andric   bool isUndef(SDValue Op) const {
4030b57cec5SDimitry Andric     if (Op.isMachineOpcode())
4040b57cec5SDimitry Andric       return Op.getMachineOpcode() == TargetOpcode::IMPLICIT_DEF;
4050b57cec5SDimitry Andric     return Op.getOpcode() == ISD::UNDEF;
4060b57cec5SDimitry Andric   }
4070b57cec5SDimitry Andric   SDValue getInstr(unsigned MachineOpc, const SDLoc &dl, MVT Ty,
4080b57cec5SDimitry Andric                    ArrayRef<SDValue> Ops, SelectionDAG &DAG) const {
4090b57cec5SDimitry Andric     SDNode *N = DAG.getMachineNode(MachineOpc, dl, Ty, Ops);
4100b57cec5SDimitry Andric     return SDValue(N, 0);
4110b57cec5SDimitry Andric   }
4120b57cec5SDimitry Andric   SDValue getZero(const SDLoc &dl, MVT Ty, SelectionDAG &DAG) const;
4130b57cec5SDimitry Andric 
4140b57cec5SDimitry Andric   using VectorPair = std::pair<SDValue, SDValue>;
4150b57cec5SDimitry Andric   using TypePair = std::pair<MVT, MVT>;
4160b57cec5SDimitry Andric 
4170b57cec5SDimitry Andric   SDValue getInt(unsigned IntId, MVT ResTy, ArrayRef<SDValue> Ops,
4180b57cec5SDimitry Andric                  const SDLoc &dl, SelectionDAG &DAG) const;
4190b57cec5SDimitry Andric 
4200b57cec5SDimitry Andric   MVT ty(SDValue Op) const {
4210b57cec5SDimitry Andric     return Op.getValueType().getSimpleVT();
4220b57cec5SDimitry Andric   }
4230b57cec5SDimitry Andric   TypePair ty(const VectorPair &Ops) const {
4240b57cec5SDimitry Andric     return { Ops.first.getValueType().getSimpleVT(),
4250b57cec5SDimitry Andric              Ops.second.getValueType().getSimpleVT() };
4260b57cec5SDimitry Andric   }
4270b57cec5SDimitry Andric   MVT tyScalar(MVT Ty) const {
4280b57cec5SDimitry Andric     if (!Ty.isVector())
4290b57cec5SDimitry Andric       return Ty;
4300b57cec5SDimitry Andric     return MVT::getIntegerVT(Ty.getSizeInBits());
4310b57cec5SDimitry Andric   }
4320b57cec5SDimitry Andric   MVT tyVector(MVT Ty, MVT ElemTy) const {
4330b57cec5SDimitry Andric     if (Ty.isVector() && Ty.getVectorElementType() == ElemTy)
4340b57cec5SDimitry Andric       return Ty;
4350b57cec5SDimitry Andric     unsigned TyWidth = Ty.getSizeInBits();
4360b57cec5SDimitry Andric     unsigned ElemWidth = ElemTy.getSizeInBits();
4370b57cec5SDimitry Andric     assert((TyWidth % ElemWidth) == 0);
4380b57cec5SDimitry Andric     return MVT::getVectorVT(ElemTy, TyWidth/ElemWidth);
4390b57cec5SDimitry Andric   }
4400b57cec5SDimitry Andric 
4410b57cec5SDimitry Andric   MVT typeJoin(const TypePair &Tys) const;
4420b57cec5SDimitry Andric   TypePair typeSplit(MVT Ty) const;
4430b57cec5SDimitry Andric   MVT typeExtElem(MVT VecTy, unsigned Factor) const;
4440b57cec5SDimitry Andric   MVT typeTruncElem(MVT VecTy, unsigned Factor) const;
445bdd1243dSDimitry Andric   TypePair typeExtendToWider(MVT Ty0, MVT Ty1) const;
446bdd1243dSDimitry Andric   TypePair typeWidenToWider(MVT Ty0, MVT Ty1) const;
447bdd1243dSDimitry Andric   MVT typeLegalize(MVT Ty, SelectionDAG &DAG) const;
448bdd1243dSDimitry Andric   MVT typeWidenToHvx(MVT Ty) const;
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric   SDValue opJoin(const VectorPair &Ops, const SDLoc &dl,
4510b57cec5SDimitry Andric                  SelectionDAG &DAG) const;
4520b57cec5SDimitry Andric   VectorPair opSplit(SDValue Vec, const SDLoc &dl, SelectionDAG &DAG) const;
4530b57cec5SDimitry Andric   SDValue opCastElem(SDValue Vec, MVT ElemTy, SelectionDAG &DAG) const;
4540b57cec5SDimitry Andric 
455bdd1243dSDimitry Andric   SDValue LoHalf(SDValue V, SelectionDAG &DAG) const {
456bdd1243dSDimitry Andric     MVT Ty = ty(V);
457bdd1243dSDimitry Andric     const SDLoc &dl(V);
458bdd1243dSDimitry Andric     if (!Ty.isVector()) {
459bdd1243dSDimitry Andric       assert(Ty.getSizeInBits() == 64);
460bdd1243dSDimitry Andric       return DAG.getTargetExtractSubreg(Hexagon::isub_lo, dl, MVT::i32, V);
461bdd1243dSDimitry Andric     }
462bdd1243dSDimitry Andric     MVT HalfTy = typeSplit(Ty).first;
463bdd1243dSDimitry Andric     SDValue Idx = getZero(dl, MVT::i32, DAG);
464bdd1243dSDimitry Andric     return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HalfTy, V, Idx);
465bdd1243dSDimitry Andric   }
466bdd1243dSDimitry Andric   SDValue HiHalf(SDValue V, SelectionDAG &DAG) const {
467bdd1243dSDimitry Andric     MVT Ty = ty(V);
468bdd1243dSDimitry Andric     const SDLoc &dl(V);
469bdd1243dSDimitry Andric     if (!Ty.isVector()) {
470bdd1243dSDimitry Andric       assert(Ty.getSizeInBits() == 64);
471bdd1243dSDimitry Andric       return DAG.getTargetExtractSubreg(Hexagon::isub_hi, dl, MVT::i32, V);
472bdd1243dSDimitry Andric     }
473bdd1243dSDimitry Andric     MVT HalfTy = typeSplit(Ty).first;
474bdd1243dSDimitry Andric     SDValue Idx = DAG.getConstant(HalfTy.getVectorNumElements(), dl, MVT::i32);
475bdd1243dSDimitry Andric     return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HalfTy, V, Idx);
476bdd1243dSDimitry Andric   }
477bdd1243dSDimitry Andric 
4785ffd83dbSDimitry Andric   bool allowsHvxMemoryAccess(MVT VecTy, MachineMemOperand::Flags Flags,
479bdd1243dSDimitry Andric                              unsigned *Fast) const;
4805ffd83dbSDimitry Andric   bool allowsHvxMisalignedMemoryAccesses(MVT VecTy,
4815ffd83dbSDimitry Andric                                          MachineMemOperand::Flags Flags,
482bdd1243dSDimitry Andric                                          unsigned *Fast) const;
483bdd1243dSDimitry Andric   void AdjustHvxInstrPostInstrSelection(MachineInstr &MI, SDNode *Node) const;
4845ffd83dbSDimitry Andric 
4850b57cec5SDimitry Andric   bool isHvxSingleTy(MVT Ty) const;
4860b57cec5SDimitry Andric   bool isHvxPairTy(MVT Ty) const;
4875ffd83dbSDimitry Andric   bool isHvxBoolTy(MVT Ty) const;
4880b57cec5SDimitry Andric   SDValue convertToByteIndex(SDValue ElemIdx, MVT ElemTy,
4890b57cec5SDimitry Andric                              SelectionDAG &DAG) const;
4900b57cec5SDimitry Andric   SDValue getIndexInWord32(SDValue Idx, MVT ElemTy, SelectionDAG &DAG) const;
4910b57cec5SDimitry Andric   SDValue getByteShuffle(const SDLoc &dl, SDValue Op0, SDValue Op1,
4920b57cec5SDimitry Andric                          ArrayRef<int> Mask, SelectionDAG &DAG) const;
4930b57cec5SDimitry Andric 
4940b57cec5SDimitry Andric   SDValue buildHvxVectorReg(ArrayRef<SDValue> Values, const SDLoc &dl,
4950b57cec5SDimitry Andric                             MVT VecTy, SelectionDAG &DAG) const;
4960b57cec5SDimitry Andric   SDValue buildHvxVectorPred(ArrayRef<SDValue> Values, const SDLoc &dl,
4970b57cec5SDimitry Andric                              MVT VecTy, SelectionDAG &DAG) const;
4980b57cec5SDimitry Andric   SDValue createHvxPrefixPred(SDValue PredV, const SDLoc &dl,
4990b57cec5SDimitry Andric                               unsigned BitBytes, bool ZeroFill,
5000b57cec5SDimitry Andric                               SelectionDAG &DAG) const;
5010b57cec5SDimitry Andric   SDValue extractHvxElementReg(SDValue VecV, SDValue IdxV, const SDLoc &dl,
5020b57cec5SDimitry Andric                                MVT ResTy, SelectionDAG &DAG) const;
5030b57cec5SDimitry Andric   SDValue extractHvxElementPred(SDValue VecV, SDValue IdxV, const SDLoc &dl,
5040b57cec5SDimitry Andric                                 MVT ResTy, SelectionDAG &DAG) const;
5050b57cec5SDimitry Andric   SDValue insertHvxElementReg(SDValue VecV, SDValue IdxV, SDValue ValV,
5060b57cec5SDimitry Andric                               const SDLoc &dl, SelectionDAG &DAG) const;
5070b57cec5SDimitry Andric   SDValue insertHvxElementPred(SDValue VecV, SDValue IdxV, SDValue ValV,
5080b57cec5SDimitry Andric                                const SDLoc &dl, SelectionDAG &DAG) const;
509bdd1243dSDimitry Andric   SDValue extractHvxSubvectorReg(SDValue OrigOp, SDValue VecV, SDValue IdxV,
510bdd1243dSDimitry Andric                                  const SDLoc &dl, MVT ResTy, SelectionDAG &DAG)
511bdd1243dSDimitry Andric                                  const;
5120b57cec5SDimitry Andric   SDValue extractHvxSubvectorPred(SDValue VecV, SDValue IdxV, const SDLoc &dl,
5130b57cec5SDimitry Andric                                   MVT ResTy, SelectionDAG &DAG) const;
5140b57cec5SDimitry Andric   SDValue insertHvxSubvectorReg(SDValue VecV, SDValue SubV, SDValue IdxV,
5150b57cec5SDimitry Andric                                 const SDLoc &dl, SelectionDAG &DAG) const;
5160b57cec5SDimitry Andric   SDValue insertHvxSubvectorPred(SDValue VecV, SDValue SubV, SDValue IdxV,
5170b57cec5SDimitry Andric                                  const SDLoc &dl, SelectionDAG &DAG) const;
5180b57cec5SDimitry Andric   SDValue extendHvxVectorPred(SDValue VecV, const SDLoc &dl, MVT ResTy,
5190b57cec5SDimitry Andric                               bool ZeroExt, SelectionDAG &DAG) const;
5205ffd83dbSDimitry Andric   SDValue compressHvxPred(SDValue VecQ, const SDLoc &dl, MVT ResTy,
5215ffd83dbSDimitry Andric                           SelectionDAG &DAG) const;
522bdd1243dSDimitry Andric   SDValue resizeToWidth(SDValue VecV, MVT ResTy, bool Signed, const SDLoc &dl,
523bdd1243dSDimitry Andric                         SelectionDAG &DAG) const;
524bdd1243dSDimitry Andric   SDValue extractSubvector(SDValue Vec, MVT SubTy, unsigned SubIdx,
525bdd1243dSDimitry Andric                            SelectionDAG &DAG) const;
526bdd1243dSDimitry Andric   VectorPair emitHvxAddWithOverflow(SDValue A, SDValue B, const SDLoc &dl,
527bdd1243dSDimitry Andric                                     bool Signed, SelectionDAG &DAG) const;
528bdd1243dSDimitry Andric   VectorPair emitHvxShiftRightRnd(SDValue Val, unsigned Amt, bool Signed,
529bdd1243dSDimitry Andric                                   SelectionDAG &DAG) const;
530bdd1243dSDimitry Andric   SDValue emitHvxMulHsV60(SDValue A, SDValue B, const SDLoc &dl,
531bdd1243dSDimitry Andric                           SelectionDAG &DAG) const;
532bdd1243dSDimitry Andric   SDValue emitHvxMulLoHiV60(SDValue A, bool SignedA, SDValue B, bool SignedB,
533bdd1243dSDimitry Andric                             const SDLoc &dl, SelectionDAG &DAG) const;
534bdd1243dSDimitry Andric   SDValue emitHvxMulLoHiV62(SDValue A, bool SignedA, SDValue B, bool SignedB,
535bdd1243dSDimitry Andric                             const SDLoc &dl, SelectionDAG &DAG) const;
5360b57cec5SDimitry Andric 
5370b57cec5SDimitry Andric   SDValue LowerHvxBuildVector(SDValue Op, SelectionDAG &DAG) const;
53804eeddc0SDimitry Andric   SDValue LowerHvxSplatVector(SDValue Op, SelectionDAG &DAG) const;
5390b57cec5SDimitry Andric   SDValue LowerHvxConcatVectors(SDValue Op, SelectionDAG &DAG) const;
5400b57cec5SDimitry Andric   SDValue LowerHvxExtractElement(SDValue Op, SelectionDAG &DAG) const;
5410b57cec5SDimitry Andric   SDValue LowerHvxInsertElement(SDValue Op, SelectionDAG &DAG) const;
5420b57cec5SDimitry Andric   SDValue LowerHvxExtractSubvector(SDValue Op, SelectionDAG &DAG) const;
5430b57cec5SDimitry Andric   SDValue LowerHvxInsertSubvector(SDValue Op, SelectionDAG &DAG) const;
5445ffd83dbSDimitry Andric   SDValue LowerHvxBitcast(SDValue Op, SelectionDAG &DAG) const;
5450b57cec5SDimitry Andric   SDValue LowerHvxAnyExt(SDValue Op, SelectionDAG &DAG) const;
5460b57cec5SDimitry Andric   SDValue LowerHvxSignExt(SDValue Op, SelectionDAG &DAG) const;
5470b57cec5SDimitry Andric   SDValue LowerHvxZeroExt(SDValue Op, SelectionDAG &DAG) const;
5480b57cec5SDimitry Andric   SDValue LowerHvxCttz(SDValue Op, SelectionDAG &DAG) const;
5490b57cec5SDimitry Andric   SDValue LowerHvxMulh(SDValue Op, SelectionDAG &DAG) const;
550bdd1243dSDimitry Andric   SDValue LowerHvxMulLoHi(SDValue Op, SelectionDAG &DAG) const;
5510b57cec5SDimitry Andric   SDValue LowerHvxExtend(SDValue Op, SelectionDAG &DAG) const;
552e8d8bef9SDimitry Andric   SDValue LowerHvxSelect(SDValue Op, SelectionDAG &DAG) const;
5530b57cec5SDimitry Andric   SDValue LowerHvxShift(SDValue Op, SelectionDAG &DAG) const;
554bdd1243dSDimitry Andric   SDValue LowerHvxFunnelShift(SDValue Op, SelectionDAG &DAG) const;
5555ffd83dbSDimitry Andric   SDValue LowerHvxIntrinsic(SDValue Op, SelectionDAG &DAG) const;
556e8d8bef9SDimitry Andric   SDValue LowerHvxMaskedOp(SDValue Op, SelectionDAG &DAG) const;
55704eeddc0SDimitry Andric   SDValue LowerHvxFpExtend(SDValue Op, SelectionDAG &DAG) const;
558bdd1243dSDimitry Andric   SDValue LowerHvxFpToInt(SDValue Op, SelectionDAG &DAG) const;
559bdd1243dSDimitry Andric   SDValue LowerHvxIntToFp(SDValue Op, SelectionDAG &DAG) const;
560bdd1243dSDimitry Andric   SDValue ExpandHvxFpToInt(SDValue Op, SelectionDAG &DAG) const;
561bdd1243dSDimitry Andric   SDValue ExpandHvxIntToFp(SDValue Op, SelectionDAG &DAG) const;
5620b57cec5SDimitry Andric 
563bdd1243dSDimitry Andric   VectorPair SplitVectorOp(SDValue Op, SelectionDAG &DAG) const;
564bdd1243dSDimitry Andric 
5650b57cec5SDimitry Andric   SDValue SplitHvxMemOp(SDValue Op, SelectionDAG &DAG) const;
566e8d8bef9SDimitry Andric   SDValue WidenHvxLoad(SDValue Op, SelectionDAG &DAG) const;
567e8d8bef9SDimitry Andric   SDValue WidenHvxStore(SDValue Op, SelectionDAG &DAG) const;
568e8d8bef9SDimitry Andric   SDValue WidenHvxSetCC(SDValue Op, SelectionDAG &DAG) const;
569bdd1243dSDimitry Andric   SDValue LegalizeHvxResize(SDValue Op, SelectionDAG &DAG) const;
570bdd1243dSDimitry Andric   SDValue ExpandHvxResizeIntoSteps(SDValue Op, SelectionDAG &DAG) const;
571bdd1243dSDimitry Andric   SDValue EqualizeFpIntConversion(SDValue Op, SelectionDAG &DAG) const;
572bdd1243dSDimitry Andric 
573bdd1243dSDimitry Andric   SDValue CreateTLWrapper(SDValue Op, SelectionDAG &DAG) const;
574bdd1243dSDimitry Andric   SDValue RemoveTLWrapper(SDValue Op, SelectionDAG &DAG) const;
5750b57cec5SDimitry Andric 
5760b57cec5SDimitry Andric   std::pair<const TargetRegisterClass*, uint8_t>
5770b57cec5SDimitry Andric   findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT)
5780b57cec5SDimitry Andric       const override;
5790b57cec5SDimitry Andric 
580bdd1243dSDimitry Andric   bool shouldSplitToHvx(MVT Ty, SelectionDAG &DAG) const;
581e8d8bef9SDimitry Andric   bool shouldWidenToHvx(MVT Ty, SelectionDAG &DAG) const;
582e8d8bef9SDimitry Andric   bool isHvxOperation(SDNode *N, SelectionDAG &DAG) const;
5830b57cec5SDimitry Andric   SDValue LowerHvxOperation(SDValue Op, SelectionDAG &DAG) const;
5845ffd83dbSDimitry Andric   void LowerHvxOperationWrapper(SDNode *N, SmallVectorImpl<SDValue> &Results,
5855ffd83dbSDimitry Andric                                 SelectionDAG &DAG) const;
5865ffd83dbSDimitry Andric   void ReplaceHvxNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
5875ffd83dbSDimitry Andric                              SelectionDAG &DAG) const;
588bdd1243dSDimitry Andric 
589bdd1243dSDimitry Andric   SDValue combineTruncateBeforeLegal(SDValue Op, DAGCombinerInfo &DCI) const;
590bdd1243dSDimitry Andric   SDValue combineConcatVectorsBeforeLegal(SDValue Op, DAGCombinerInfo & DCI)
591bdd1243dSDimitry Andric       const;
592bdd1243dSDimitry Andric   SDValue combineVectorShuffleBeforeLegal(SDValue Op, DAGCombinerInfo & DCI)
593bdd1243dSDimitry Andric       const;
594bdd1243dSDimitry Andric 
5958bcb0991SDimitry Andric   SDValue PerformHvxDAGCombine(SDNode * N, DAGCombinerInfo & DCI) const;
5960b57cec5SDimitry Andric };
5970b57cec5SDimitry Andric 
5980b57cec5SDimitry Andric } // end namespace llvm
5990b57cec5SDimitry Andric 
6000b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
601