brintos

brintos / llvm-project-archived public Read only

0
0
Text · 29.0 KiB · f4d2a79 Raw
627 lines · c
1//===-- HexagonISelLowering.h - Hexagon DAG Lowering Interface --*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines the interfaces that Hexagon uses to lower LLVM code into a10// selection DAG.11//12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H15#define LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H16 17#include "Hexagon.h"18#include "MCTargetDesc/HexagonMCTargetDesc.h"19#include "llvm/ADT/StringRef.h"20#include "llvm/CodeGen/ISDOpcodes.h"21#include "llvm/CodeGen/SelectionDAGNodes.h"22#include "llvm/CodeGen/TargetLowering.h"23#include "llvm/CodeGen/ValueTypes.h"24#include "llvm/CodeGenTypes/MachineValueType.h"25#include "llvm/IR/CallingConv.h"26#include "llvm/IR/InlineAsm.h"27#include <cstdint>28#include <utility>29 30namespace llvm {31 32namespace HexagonISD {33 34// clang-format off35enum NodeType : unsigned {36  OP_BEGIN = ISD::BUILTIN_OP_END,37 38  CONST32 = OP_BEGIN,39  CONST32_GP,  // For marking data present in GP.40  ADDC,        // Add with carry: (X, Y, Cin) -> (X+Y, Cout).41  SUBC,        // Sub with carry: (X, Y, Cin) -> (X+~Y+Cin, Cout).42  ALLOCA,43 44  AT_GOT,      // Index in GOT.45  AT_PCREL,    // Offset relative to PC.46 47  CALL,        // Function call.48  CALLnr,      // Function call that does not return.49  CALLR,50 51  RET_GLUE,    // Return with a glue operand.52  BARRIER,     // Memory barrier.53  JT,          // Jump table.54  CP,          // Constant pool.55 56  COMBINE,57  VASL,        // Vector shifts by a scalar value58  VASR,59  VLSR,60  MFSHL,       // Funnel shifts with the shift amount guaranteed to be61  MFSHR,       // within the range of the bit width of the element.62 63  SSAT,        // Signed saturate.64  USAT,        // Unsigned saturate.65  SMUL_LOHI,   // Same as ISD::SMUL_LOHI, but opaque to the combiner.66  UMUL_LOHI,   // Same as ISD::UMUL_LOHI, but opaque to the combiner.67               // We want to legalize MULH[SU] to [SU]MUL_LOHI, but the68               // combiner will keep rewriting it back to MULH[SU].69  USMUL_LOHI,  // Like SMUL_LOHI, but unsigned*signed.70 71  TSTBIT,72  INSERT,73  EXTRACTU,74  VEXTRACTW,75  VINSERTW0,76  VROR,77  TC_RETURN,78  EH_RETURN,79  DCFETCH,80  READCYCLE,81  READTIMER,82  THREAD_POINTER,83  PTRUE,84  PFALSE,85  D2P,         // Convert 8-byte value to 8-bit predicate register. [*]86  P2D,         // Convert 8-bit predicate register to 8-byte value. [*]87  V2Q,         // Convert HVX vector to a vector predicate reg. [*]88  Q2V,         // Convert vector predicate to an HVX vector. [*]89               // [*] The equivalence is defined as "Q <=> (V != 0)",90               //     where the != operation compares bytes.91               // Note: V != 0 is implemented as V >u 0.92  QCAT,93  QTRUE,94  QFALSE,95 96  TL_EXTEND,   // Wrappers for ISD::*_EXTEND and ISD::TRUNCATE to prevent DAG97  TL_TRUNCATE, // from auto-folding operations, e.g.98               // (i32 ext (i16 ext i8)) would be folded to (i32 ext i8).99               // To simplify the type legalization, we want to keep these100               // single steps separate during type legalization.101               // TL_[EXTEND|TRUNCATE] Inp, i128 _, i32 Opc102               // * Inp is the original input to extend/truncate,103               // * _ is a dummy operand with an illegal type (can be undef),104               // * Opc is the original opcode.105               // The legalization process (in Hexagon lowering code) will106               // first deal with the "real" types (i.e. Inp and the result),107               // and once all of them are processed, the wrapper node will108               // be replaced with the original ISD node. The dummy illegal109               // operand is there to make sure that the legalization hooks110               // are called again after everything else is legal, giving111               // us the opportunity to undo the wrapping.112 113  TYPECAST,    // No-op that's used to convert between different legal114               // types in a register.115  VALIGN,      // Align two vectors (in Op0, Op1) to one that would have116               // been loaded from address in Op2.117  VALIGNADDR,  // Align vector address: Op0 & -Op1, except when it is118               // an address in a vector load, then it's a no-op.119  ISEL,        // Marker for nodes that were created during ISel, and120               // which need explicit selection (would have been left121               // unselected otherwise).122  OP_END123};124 125} // end namespace HexagonISD126// clang-format on127 128class HexagonSubtarget;129 130class HexagonTargetLowering : public TargetLowering {131  int VarArgsFrameOffset;   // Frame offset to start of varargs area.132  const HexagonTargetMachine &HTM;133  const HexagonSubtarget &Subtarget;134 135public:136  explicit HexagonTargetLowering(const TargetMachine &TM,137                                 const HexagonSubtarget &ST);138 139  /// IsEligibleForTailCallOptimization - Check whether the call is eligible140  /// for tail call optimization. Targets which want to do tail call141  /// optimization should implement this function.142  bool IsEligibleForTailCallOptimization(SDValue Callee,143      CallingConv::ID CalleeCC, bool isVarArg, bool isCalleeStructRet,144      bool isCallerStructRet, const SmallVectorImpl<ISD::OutputArg> &Outs,145      const SmallVectorImpl<SDValue> &OutVals,146      const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG& DAG) const;147 148  bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I,149                          MachineFunction &MF,150                          unsigned Intrinsic) const override;151 152  bool isTruncateFree(Type *Ty1, Type *Ty2) const override;153  bool isTruncateFree(EVT VT1, EVT VT2) const override;154 155  bool isCheapToSpeculateCttz(Type *) const override { return true; }156  bool isCheapToSpeculateCtlz(Type *) const override { return true; }157  bool isCtlzFast() const override { return true; }158 159  bool hasBitTest(SDValue X, SDValue Y) const override;160 161  bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override;162 163  bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override;164 165  bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override;166 167  /// Return true if an FMA operation is faster than a pair of mul and add168  /// instructions. fmuladd intrinsics will be expanded to FMAs when this169  /// method returns true (and FMAs are legal), otherwise fmuladd is170  /// expanded to mul + add.171  bool isFMAFasterThanFMulAndFAdd(const MachineFunction &,172                                  EVT) const override;173 174  // Should we expand the build vector with shuffles?175  bool shouldExpandBuildVectorWithShuffles(EVT VT,176      unsigned DefinedValues) const override;177  bool isExtractSubvectorCheap(EVT ResVT, EVT SrcVT,178      unsigned Index) const override;179 180  bool isTargetCanonicalConstantNode(SDValue Op) const override;181 182  bool isShuffleMaskLegal(ArrayRef<int> Mask, EVT VT) const override;183  LegalizeTypeAction getPreferredVectorAction(MVT VT) const override;184  LegalizeAction getCustomOperationAction(SDNode &Op) const override;185 186  SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;187  void LowerOperationWrapper(SDNode *N, SmallVectorImpl<SDValue> &Results,188                             SelectionDAG &DAG) const override;189  void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,190                          SelectionDAG &DAG) const override;191 192  const char *getTargetNodeName(unsigned Opcode) const override;193  std::pair<MVT, unsigned>194  handleMaskRegisterForCallingConv(const HexagonSubtarget &Subtarget,195                                   EVT VT) const;196 197  SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;198  SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;199  SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;200  SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;201  SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;202  SDValue LowerINSERT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;203  SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;204  SDValue LowerVECTOR_SHIFT(SDValue Op, SelectionDAG &DAG) const;205  SDValue LowerROTL(SDValue Op, SelectionDAG &DAG) const;206  SDValue LowerBITCAST(SDValue Op, SelectionDAG &DAG) const;207  SDValue LowerANY_EXTEND(SDValue Op, SelectionDAG &DAG) const;208  SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) const;209  SDValue LowerZERO_EXTEND(SDValue Op, SelectionDAG &DAG) const;210  SDValue LowerLoad(SDValue Op, SelectionDAG &DAG) const;211  SDValue LowerStore(SDValue Op, SelectionDAG &DAG) const;212  SDValue LowerUnalignedLoad(SDValue Op, SelectionDAG &DAG) const;213  SDValue LowerUAddSubO(SDValue Op, SelectionDAG &DAG) const;214  SDValue LowerUAddSubOCarry(SDValue Op, SelectionDAG &DAG) const;215 216  SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;217  SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;218  SDValue LowerFDIV(SDValue Op, SelectionDAG &DAG) const;219  SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;220  SDValue LowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const;221  SDValue LowerREADSTEADYCOUNTER(SDValue Op, SelectionDAG &DAG) const;222  SDValue LowerEH_LABEL(SDValue Op, SelectionDAG &DAG) const;223  SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;224  SDValue225  LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,226                       const SmallVectorImpl<ISD::InputArg> &Ins,227                       const SDLoc &dl, SelectionDAG &DAG,228                       SmallVectorImpl<SDValue> &InVals) const override;229  SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const;230  SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;231  SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;232  SDValue LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,233      SelectionDAG &DAG) const;234  SDValue LowerToTLSInitialExecModel(GlobalAddressSDNode *GA,235      SelectionDAG &DAG) const;236  SDValue LowerToTLSLocalExecModel(GlobalAddressSDNode *GA,237      SelectionDAG &DAG) const;238  SDValue GetDynamicTLSAddr(SelectionDAG &DAG, SDValue Chain,239      GlobalAddressSDNode *GA, SDValue InGlue, EVT PtrVT,240      unsigned ReturnReg, unsigned char OperandGlues) const;241  SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG) const;242 243  SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,244      SmallVectorImpl<SDValue> &InVals) const override;245  SDValue LowerCallResult(SDValue Chain, SDValue InGlue,246                          CallingConv::ID CallConv, bool isVarArg,247                          const SmallVectorImpl<ISD::InputArg> &Ins,248                          const SDLoc &dl, SelectionDAG &DAG,249                          SmallVectorImpl<SDValue> &InVals,250                          const SmallVectorImpl<SDValue> &OutVals,251                          SDValue Callee) const;252 253  SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;254  SDValue LowerVSELECT(SDValue Op, SelectionDAG &DAG) const;255  SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;256  SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;257  SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;258 259  bool CanLowerReturn(CallingConv::ID CallConv,260                      MachineFunction &MF, bool isVarArg,261                      const SmallVectorImpl<ISD::OutputArg> &Outs,262                      LLVMContext &Context, const Type *RetTy) const override;263 264  SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,265                      const SmallVectorImpl<ISD::OutputArg> &Outs,266                      const SmallVectorImpl<SDValue> &OutVals,267                      const SDLoc &dl, SelectionDAG &DAG) const override;268 269  SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;270 271  bool mayBeEmittedAsTailCall(const CallInst *CI) const override;272 273  Register getRegisterByName(const char* RegName, LLT VT,274                             const MachineFunction &MF) const override;275 276  unsigned getVectorTypeBreakdownForCallingConv(LLVMContext &Context,277                                                CallingConv::ID CC, EVT VT,278                                                EVT &IntermediateVT,279                                                unsigned &NumIntermediates,280                                                MVT &RegisterVT) const override;281 282  MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC,283                                    EVT VT) const override;284  /// If a physical register, this returns the register that receives the285  /// exception address on entry to an EH pad.286  Register287  getExceptionPointerRegister(const Constant *PersonalityFn) const override {288    return Hexagon::R0;289  }290 291  /// If a physical register, this returns the register that receives the292  /// exception typeid on entry to a landing pad.293  Register294  getExceptionSelectorRegister(const Constant *PersonalityFn) const override {295    return Hexagon::R1;296  }297 298  SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;299  SDValue LowerVACOPY(SDValue Op, SelectionDAG &DAG) const;300  SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;301  SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;302 303  EVT getSetCCResultType(const DataLayout &, LLVMContext &C,304                         EVT VT) const override {305    if (!VT.isVector())306      return MVT::i1;307    else308      return EVT::getVectorVT(C, MVT::i1, VT.getVectorNumElements());309  }310 311  bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,312                                  SDValue &Base, SDValue &Offset,313                                  ISD::MemIndexedMode &AM,314                                  SelectionDAG &DAG) const override;315 316  ConstraintType getConstraintType(StringRef Constraint) const override;317 318  std::pair<unsigned, const TargetRegisterClass *>319  getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,320                               StringRef Constraint, MVT VT) const override;321 322  // Intrinsics323  SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;324  SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;325  /// isLegalAddressingMode - Return true if the addressing mode represented326  /// by AM is legal for this target, for a load/store of the specified type.327  /// The type may be VoidTy, in which case only return true if the addressing328  /// mode is legal for a load/store of any legal type.329  /// TODO: Handle pre/postinc as well.330  bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,331                             Type *Ty, unsigned AS,332                             Instruction *I = nullptr) const override;333  /// Return true if folding a constant offset with the given GlobalAddress334  /// is legal.  It is frequently not legal in PIC relocation models.335  bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;336 337  bool isFPImmLegal(const APFloat &Imm, EVT VT,338                    bool ForCodeSize) const override;339 340  /// isLegalICmpImmediate - Return true if the specified immediate is legal341  /// icmp immediate, that is the target has icmp instructions which can342  /// compare a register against the immediate without having to materialize343  /// the immediate into a register.344  bool isLegalICmpImmediate(int64_t Imm) const override;345 346  EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,347                          const AttributeList &FuncAttributes) const override;348 349  bool allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, EVT VT,350                          unsigned AddrSpace, Align Alignment,351                          MachineMemOperand::Flags Flags,352                          unsigned *Fast) const override;353 354  bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace,355                                      Align Alignment,356                                      MachineMemOperand::Flags Flags,357                                      unsigned *Fast) const override;358 359  /// Returns relocation base for the given PIC jumptable.360  SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG)361                                   const override;362 363  /// Returns true if it is beneficial to convert a load of a constant364  /// to just the constant itself.365  bool shouldConvertConstantLoadToIntImm(const APInt &Imm,366                                         Type *Ty) const override;367 368  bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy, EVT NewVT,369                             std::optional<unsigned> ByteOffset) const override;370 371  void AdjustInstrPostInstrSelection(MachineInstr &MI,372                                     SDNode *Node) const override;373 374  // Handling of atomic RMW instructions.375  Value *emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr,376                        AtomicOrdering Ord) const override;377  Value *emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr,378                              AtomicOrdering Ord) const override;379  AtomicExpansionKind shouldExpandAtomicLoadInIR(LoadInst *LI) const override;380  AtomicExpansionKind shouldExpandAtomicStoreInIR(StoreInst *SI) const override;381  AtomicExpansionKind382  shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override;383 384  AtomicExpansionKind385  shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override {386    return AtomicExpansionKind::LLSC;387  }388  bool softPromoteHalfType() const override { return true; }389 390private:391  void initializeHVXLowering();392  unsigned getPreferredHvxVectorAction(MVT VecTy) const;393  unsigned getCustomHvxOperationAction(SDNode &Op) const;394 395  bool validateConstPtrAlignment(SDValue Ptr, Align NeedAlign, const SDLoc &dl,396                                 SelectionDAG &DAG) const;397  SDValue replaceMemWithUndef(SDValue Op, SelectionDAG &DAG) const;398 399  std::pair<SDValue,int> getBaseAndOffset(SDValue Addr) const;400 401  bool getBuildVectorConstInts(ArrayRef<SDValue> Values, MVT VecTy,402                               SelectionDAG &DAG,403                               MutableArrayRef<ConstantInt*> Consts) const;404  SDValue buildVector32(ArrayRef<SDValue> Elem, const SDLoc &dl, MVT VecTy,405                        SelectionDAG &DAG) const;406  SDValue buildVector64(ArrayRef<SDValue> Elem, const SDLoc &dl, MVT VecTy,407                        SelectionDAG &DAG) const;408  SDValue extractVector(SDValue VecV, SDValue IdxV, const SDLoc &dl,409                        MVT ValTy, MVT ResTy, SelectionDAG &DAG) const;410  SDValue extractVectorPred(SDValue VecV, SDValue IdxV, const SDLoc &dl,411                            MVT ValTy, MVT ResTy, SelectionDAG &DAG) const;412  SDValue insertVector(SDValue VecV, SDValue ValV, SDValue IdxV,413                       const SDLoc &dl, MVT ValTy, SelectionDAG &DAG) const;414  SDValue insertVectorPred(SDValue VecV, SDValue ValV, SDValue IdxV,415                           const SDLoc &dl, MVT ValTy, SelectionDAG &DAG) const;416  SDValue expandPredicate(SDValue Vec32, const SDLoc &dl,417                          SelectionDAG &DAG) const;418  SDValue contractPredicate(SDValue Vec64, const SDLoc &dl,419                            SelectionDAG &DAG) const;420  SDValue getSplatValue(SDValue Op, SelectionDAG &DAG) const;421  SDValue getVectorShiftByInt(SDValue Op, SelectionDAG &DAG) const;422  SDValue appendUndef(SDValue Val, MVT ResTy, SelectionDAG &DAG) const;423  SDValue getCombine(SDValue Hi, SDValue Lo, const SDLoc &dl, MVT ResTy,424                     SelectionDAG &DAG) const;425 426  bool isUndef(SDValue Op) const {427    if (Op.isMachineOpcode())428      return Op.getMachineOpcode() == TargetOpcode::IMPLICIT_DEF;429    return Op.getOpcode() == ISD::UNDEF;430  }431  SDValue getInstr(unsigned MachineOpc, const SDLoc &dl, MVT Ty,432                   ArrayRef<SDValue> Ops, SelectionDAG &DAG) const {433    SDNode *N = DAG.getMachineNode(MachineOpc, dl, Ty, Ops);434    return SDValue(N, 0);435  }436  SDValue getZero(const SDLoc &dl, MVT Ty, SelectionDAG &DAG) const;437 438  using VectorPair = std::pair<SDValue, SDValue>;439  using TypePair = std::pair<MVT, MVT>;440 441  SDValue getInt(unsigned IntId, MVT ResTy, ArrayRef<SDValue> Ops,442                 const SDLoc &dl, SelectionDAG &DAG) const;443 444  MVT ty(SDValue Op) const {445    return Op.getValueType().getSimpleVT();446  }447  TypePair ty(const VectorPair &Ops) const {448    return { Ops.first.getValueType().getSimpleVT(),449             Ops.second.getValueType().getSimpleVT() };450  }451  MVT tyScalar(MVT Ty) const {452    if (!Ty.isVector())453      return Ty;454    return MVT::getIntegerVT(Ty.getSizeInBits());455  }456  MVT tyVector(MVT Ty, MVT ElemTy) const {457    if (Ty.isVector() && Ty.getVectorElementType() == ElemTy)458      return Ty;459    unsigned TyWidth = Ty.getSizeInBits();460    unsigned ElemWidth = ElemTy.getSizeInBits();461    assert((TyWidth % ElemWidth) == 0);462    return MVT::getVectorVT(ElemTy, TyWidth/ElemWidth);463  }464 465  MVT typeJoin(const TypePair &Tys) const;466  TypePair typeSplit(MVT Ty) const;467  MVT typeExtElem(MVT VecTy, unsigned Factor) const;468  MVT typeTruncElem(MVT VecTy, unsigned Factor) const;469  TypePair typeExtendToWider(MVT Ty0, MVT Ty1) const;470  TypePair typeWidenToWider(MVT Ty0, MVT Ty1) const;471  MVT typeLegalize(MVT Ty, SelectionDAG &DAG) const;472  MVT typeWidenToHvx(MVT Ty) const;473 474  SDValue opJoin(const VectorPair &Ops, const SDLoc &dl,475                 SelectionDAG &DAG) const;476  VectorPair opSplit(SDValue Vec, const SDLoc &dl, SelectionDAG &DAG) const;477  SDValue opCastElem(SDValue Vec, MVT ElemTy, SelectionDAG &DAG) const;478 479  SDValue LoHalf(SDValue V, SelectionDAG &DAG) const {480    MVT Ty = ty(V);481    const SDLoc &dl(V);482    if (!Ty.isVector()) {483      assert(Ty.getSizeInBits() == 64);484      return DAG.getTargetExtractSubreg(Hexagon::isub_lo, dl, MVT::i32, V);485    }486    MVT HalfTy = typeSplit(Ty).first;487    SDValue Idx = getZero(dl, MVT::i32, DAG);488    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HalfTy, V, Idx);489  }490  SDValue HiHalf(SDValue V, SelectionDAG &DAG) const {491    MVT Ty = ty(V);492    const SDLoc &dl(V);493    if (!Ty.isVector()) {494      assert(Ty.getSizeInBits() == 64);495      return DAG.getTargetExtractSubreg(Hexagon::isub_hi, dl, MVT::i32, V);496    }497    MVT HalfTy = typeSplit(Ty).first;498    SDValue Idx = DAG.getConstant(HalfTy.getVectorNumElements(), dl, MVT::i32);499    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HalfTy, V, Idx);500  }501 502  bool allowsHvxMemoryAccess(MVT VecTy, MachineMemOperand::Flags Flags,503                             unsigned *Fast) const;504  bool allowsHvxMisalignedMemoryAccesses(MVT VecTy,505                                         MachineMemOperand::Flags Flags,506                                         unsigned *Fast) const;507  void AdjustHvxInstrPostInstrSelection(MachineInstr &MI, SDNode *Node) const;508 509  bool isHvxSingleTy(MVT Ty) const;510  bool isHvxPairTy(MVT Ty) const;511  bool isHvxBoolTy(MVT Ty) const;512  SDValue convertToByteIndex(SDValue ElemIdx, MVT ElemTy,513                             SelectionDAG &DAG) const;514  SDValue getIndexInWord32(SDValue Idx, MVT ElemTy, SelectionDAG &DAG) const;515  SDValue getByteShuffle(const SDLoc &dl, SDValue Op0, SDValue Op1,516                         ArrayRef<int> Mask, SelectionDAG &DAG) const;517 518  SDValue buildHvxVectorReg(ArrayRef<SDValue> Values, const SDLoc &dl,519                            MVT VecTy, SelectionDAG &DAG) const;520  SDValue buildHvxVectorPred(ArrayRef<SDValue> Values, const SDLoc &dl,521                             MVT VecTy, SelectionDAG &DAG) const;522  SDValue createHvxPrefixPred(SDValue PredV, const SDLoc &dl,523                              unsigned BitBytes, bool ZeroFill,524                              SelectionDAG &DAG) const;525  SDValue extractHvxElementReg(SDValue VecV, SDValue IdxV, const SDLoc &dl,526                               MVT ResTy, SelectionDAG &DAG) const;527  SDValue extractHvxElementPred(SDValue VecV, SDValue IdxV, const SDLoc &dl,528                                MVT ResTy, SelectionDAG &DAG) const;529  SDValue insertHvxElementReg(SDValue VecV, SDValue IdxV, SDValue ValV,530                              const SDLoc &dl, SelectionDAG &DAG) const;531  SDValue insertHvxElementPred(SDValue VecV, SDValue IdxV, SDValue ValV,532                               const SDLoc &dl, SelectionDAG &DAG) const;533  SDValue extractHvxSubvectorReg(SDValue OrigOp, SDValue VecV, SDValue IdxV,534                                 const SDLoc &dl, MVT ResTy, SelectionDAG &DAG)535                                 const;536  SDValue extractHvxSubvectorPred(SDValue VecV, SDValue IdxV, const SDLoc &dl,537                                  MVT ResTy, SelectionDAG &DAG) const;538  SDValue insertHvxSubvectorReg(SDValue VecV, SDValue SubV, SDValue IdxV,539                                const SDLoc &dl, SelectionDAG &DAG) const;540  SDValue insertHvxSubvectorPred(SDValue VecV, SDValue SubV, SDValue IdxV,541                                 const SDLoc &dl, SelectionDAG &DAG) const;542  SDValue extendHvxVectorPred(SDValue VecV, const SDLoc &dl, MVT ResTy,543                              bool ZeroExt, SelectionDAG &DAG) const;544  SDValue compressHvxPred(SDValue VecQ, const SDLoc &dl, MVT ResTy,545                          SelectionDAG &DAG) const;546  SDValue resizeToWidth(SDValue VecV, MVT ResTy, bool Signed, const SDLoc &dl,547                        SelectionDAG &DAG) const;548  SDValue extractSubvector(SDValue Vec, MVT SubTy, unsigned SubIdx,549                           SelectionDAG &DAG) const;550  VectorPair emitHvxAddWithOverflow(SDValue A, SDValue B, const SDLoc &dl,551                                    bool Signed, SelectionDAG &DAG) const;552  VectorPair emitHvxShiftRightRnd(SDValue Val, unsigned Amt, bool Signed,553                                  SelectionDAG &DAG) const;554  SDValue emitHvxMulHsV60(SDValue A, SDValue B, const SDLoc &dl,555                          SelectionDAG &DAG) const;556  SDValue emitHvxMulLoHiV60(SDValue A, bool SignedA, SDValue B, bool SignedB,557                            const SDLoc &dl, SelectionDAG &DAG) const;558  SDValue emitHvxMulLoHiV62(SDValue A, bool SignedA, SDValue B, bool SignedB,559                            const SDLoc &dl, SelectionDAG &DAG) const;560 561  SDValue LowerHvxBuildVector(SDValue Op, SelectionDAG &DAG) const;562  SDValue LowerHvxSplatVector(SDValue Op, SelectionDAG &DAG) const;563  SDValue LowerHvxConcatVectors(SDValue Op, SelectionDAG &DAG) const;564  SDValue LowerHvxExtractElement(SDValue Op, SelectionDAG &DAG) const;565  SDValue LowerHvxInsertElement(SDValue Op, SelectionDAG &DAG) const;566  SDValue LowerHvxExtractSubvector(SDValue Op, SelectionDAG &DAG) const;567  SDValue LowerHvxInsertSubvector(SDValue Op, SelectionDAG &DAG) const;568  SDValue LowerHvxBitcast(SDValue Op, SelectionDAG &DAG) const;569  SDValue LowerHvxAnyExt(SDValue Op, SelectionDAG &DAG) const;570  SDValue LowerHvxSignExt(SDValue Op, SelectionDAG &DAG) const;571  SDValue LowerHvxZeroExt(SDValue Op, SelectionDAG &DAG) const;572  SDValue LowerHvxCttz(SDValue Op, SelectionDAG &DAG) const;573  SDValue LowerHvxMulh(SDValue Op, SelectionDAG &DAG) const;574  SDValue LowerHvxMulLoHi(SDValue Op, SelectionDAG &DAG) const;575  SDValue LowerHvxExtend(SDValue Op, SelectionDAG &DAG) const;576  SDValue LowerHvxSelect(SDValue Op, SelectionDAG &DAG) const;577  SDValue LowerHvxShift(SDValue Op, SelectionDAG &DAG) const;578  SDValue LowerHvxFunnelShift(SDValue Op, SelectionDAG &DAG) const;579  SDValue LowerHvxIntrinsic(SDValue Op, SelectionDAG &DAG) const;580  SDValue LowerHvxMaskedOp(SDValue Op, SelectionDAG &DAG) const;581  SDValue LowerHvxFpExtend(SDValue Op, SelectionDAG &DAG) const;582  SDValue LowerHvxFpToInt(SDValue Op, SelectionDAG &DAG) const;583  SDValue LowerHvxIntToFp(SDValue Op, SelectionDAG &DAG) const;584  SDValue LowerHvxPred32ToFp(SDValue Op, SelectionDAG &DAG) const;585  SDValue LowerHvxPred64ToFp(SDValue Op, SelectionDAG &DAG) const;586  SDValue ExpandHvxFpToInt(SDValue Op, SelectionDAG &DAG) const;587  SDValue ExpandHvxIntToFp(SDValue Op, SelectionDAG &DAG) const;588 589  VectorPair SplitVectorOp(SDValue Op, SelectionDAG &DAG) const;590 591  SDValue SplitHvxMemOp(SDValue Op, SelectionDAG &DAG) const;592  SDValue WidenHvxLoad(SDValue Op, SelectionDAG &DAG) const;593  SDValue WidenHvxStore(SDValue Op, SelectionDAG &DAG) const;594  SDValue WidenHvxSetCC(SDValue Op, SelectionDAG &DAG) const;595  SDValue LegalizeHvxResize(SDValue Op, SelectionDAG &DAG) const;596  SDValue ExpandHvxResizeIntoSteps(SDValue Op, SelectionDAG &DAG) const;597  SDValue EqualizeFpIntConversion(SDValue Op, SelectionDAG &DAG) const;598 599  SDValue CreateTLWrapper(SDValue Op, SelectionDAG &DAG) const;600  SDValue RemoveTLWrapper(SDValue Op, SelectionDAG &DAG) const;601 602  std::pair<const TargetRegisterClass*, uint8_t>603  findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT)604      const override;605 606  bool shouldSplitToHvx(MVT Ty, SelectionDAG &DAG) const;607  bool shouldWidenToHvx(MVT Ty, SelectionDAG &DAG) const;608  bool isHvxOperation(SDNode *N, SelectionDAG &DAG) const;609  SDValue LowerHvxOperation(SDValue Op, SelectionDAG &DAG) const;610  void LowerHvxOperationWrapper(SDNode *N, SmallVectorImpl<SDValue> &Results,611                                SelectionDAG &DAG) const;612  void ReplaceHvxNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,613                             SelectionDAG &DAG) const;614 615  SDValue combineTruncateBeforeLegal(SDValue Op, DAGCombinerInfo &DCI) const;616  SDValue combineConcatVectorsBeforeLegal(SDValue Op, DAGCombinerInfo & DCI)617      const;618  SDValue combineVectorShuffleBeforeLegal(SDValue Op, DAGCombinerInfo & DCI)619      const;620 621  SDValue PerformHvxDAGCombine(SDNode * N, DAGCombinerInfo & DCI) const;622};623 624} // end namespace llvm625 626#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H627