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