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