1 //===-- HexagonISelLowering.h - Hexagon DAG Lowering Interface --*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the interfaces that Hexagon uses to lower LLVM code into a 11 // selection DAG. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H 16 #define LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H 17 18 #include "Hexagon.h" 19 #include "llvm/CodeGen/CallingConvLower.h" 20 #include "llvm/IR/CallingConv.h" 21 #include "llvm/Target/TargetLowering.h" 22 23 namespace llvm { 24 25 // Return true when the given node fits in a positive half word. 26 bool isPositiveHalfWord(SDNode *N); 27 28 namespace HexagonISD { 29 enum NodeType : unsigned { 30 OP_BEGIN = ISD::BUILTIN_OP_END, 31 32 CONST32 = OP_BEGIN, 33 CONST32_GP, // For marking data present in GP. 34 FCONST32, 35 ALLOCA, 36 ARGEXTEND, 37 38 PIC_ADD, 39 AT_GOT, 40 AT_PCREL, 41 42 CALLv3, // A V3+ call instruction. 43 CALLv3nr, // A V3+ call instruction that doesn't return. 44 CALLR, 45 46 RET_FLAG, // Return with a flag operand. 47 BR_JT, // Branch through jump table. 48 BARRIER, // Memory barrier. 49 JT, // Jump table. 50 CP, // Constant pool. 51 52 POPCOUNT, 53 COMBINE, 54 PACKHL, 55 VSPLATB, 56 VSPLATH, 57 SHUFFEB, 58 SHUFFEH, 59 SHUFFOB, 60 SHUFFOH, 61 VSXTBH, 62 VSXTBW, 63 VSRAW, 64 VSRAH, 65 VSRLW, 66 VSRLH, 67 VSHLW, 68 VSHLH, 69 VCMPBEQ, 70 VCMPBGT, 71 VCMPBGTU, 72 VCMPHEQ, 73 VCMPHGT, 74 VCMPHGTU, 75 VCMPWEQ, 76 VCMPWGT, 77 VCMPWGTU, 78 79 INSERT, 80 INSERTRP, 81 EXTRACTU, 82 EXTRACTURP, 83 TC_RETURN, 84 EH_RETURN, 85 DCFETCH, 86 87 OP_END 88 }; 89 } 90 91 class HexagonSubtarget; 92 93 class HexagonTargetLowering : public TargetLowering { 94 int VarArgsFrameOffset; // Frame offset to start of varargs area. 95 96 bool CanReturnSmallStruct(const Function* CalleeFn, unsigned& RetSize) 97 const; 98 void promoteLdStType(EVT VT, EVT PromotedLdStVT); 99 const HexagonTargetMachine &HTM; 100 const HexagonSubtarget &Subtarget; 101 102 public: 103 explicit HexagonTargetLowering(const TargetMachine &TM, 104 const HexagonSubtarget &ST); 105 106 /// IsEligibleForTailCallOptimization - Check whether the call is eligible 107 /// for tail call optimization. Targets which want to do tail call 108 /// optimization should implement this function. 109 bool IsEligibleForTailCallOptimization(SDValue Callee, 110 CallingConv::ID CalleeCC, bool isVarArg, bool isCalleeStructRet, 111 bool isCallerStructRet, const SmallVectorImpl<ISD::OutputArg> &Outs, 112 const SmallVectorImpl<SDValue> &OutVals, 113 const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG& DAG) const; 114 115 bool isTruncateFree(Type *Ty1, Type *Ty2) const override; 116 bool isTruncateFree(EVT VT1, EVT VT2) const override; 117 118 bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override; 119 120 // Should we expand the build vector with shuffles? 121 bool shouldExpandBuildVectorWithShuffles(EVT VT, 122 unsigned DefinedValues) const override; 123 124 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 125 const char *getTargetNodeName(unsigned Opcode) const override; 126 SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const; 127 SDValue LowerEXTRACT_VECTOR(SDValue Op, SelectionDAG &DAG) const; 128 SDValue LowerINSERT_VECTOR(SDValue Op, SelectionDAG &DAG) const; 129 SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; 130 SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const; 131 SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; 132 SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const; 133 SDValue LowerEH_LABEL(SDValue Op, SelectionDAG &DAG) const; 134 SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const; 135 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, 136 bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc dl, 137 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const override; 138 SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const; 139 SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 140 141 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, 142 SmallVectorImpl<SDValue> &InVals) const override; 143 SDValue LowerCallResult(SDValue Chain, SDValue InFlag, 144 CallingConv::ID CallConv, bool isVarArg, 145 const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc dl, 146 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, 147 const SmallVectorImpl<SDValue> &OutVals, SDValue Callee) const; 148 149 SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; 150 SDValue LowerVSELECT(SDValue Op, SelectionDAG &DAG) const; 151 SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) const; 152 SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; 153 SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const; 154 SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; 155 SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const; 156 157 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, 158 bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, 159 const SmallVectorImpl<SDValue> &OutVals, SDLoc dl, 160 SelectionDAG &DAG) const override; 161 162 bool mayBeEmittedAsTailCall(CallInst *CI) const override; 163 MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, 164 MachineBasicBlock *BB) const override; 165 166 SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; 167 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; getSetCCResultType(const DataLayout &,LLVMContext & C,EVT VT)168 EVT getSetCCResultType(const DataLayout &, LLVMContext &C, 169 EVT VT) const override { 170 if (!VT.isVector()) 171 return MVT::i1; 172 else 173 return EVT::getVectorVT(C, MVT::i1, VT.getVectorNumElements()); 174 } 175 176 bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, 177 SDValue &Base, SDValue &Offset, 178 ISD::MemIndexedMode &AM, 179 SelectionDAG &DAG) const override; 180 181 std::pair<unsigned, const TargetRegisterClass *> 182 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 183 StringRef Constraint, MVT VT) const override; 184 185 unsigned getInlineAsmMemConstraint(StringRef ConstraintCode)186 getInlineAsmMemConstraint(StringRef ConstraintCode) const override { 187 if (ConstraintCode == "o") 188 return InlineAsm::Constraint_o; 189 else if (ConstraintCode == "v") 190 return InlineAsm::Constraint_v; 191 return TargetLowering::getInlineAsmMemConstraint(ConstraintCode); 192 } 193 194 // Intrinsics 195 SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; 196 /// isLegalAddressingMode - Return true if the addressing mode represented 197 /// by AM is legal for this target, for a load/store of the specified type. 198 /// The type may be VoidTy, in which case only return true if the addressing 199 /// mode is legal for a load/store of any legal type. 200 /// TODO: Handle pre/postinc as well. 201 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, 202 Type *Ty, unsigned AS) const override; 203 bool isFPImmLegal(const APFloat &Imm, EVT VT) const override; 204 205 /// isLegalICmpImmediate - Return true if the specified immediate is legal 206 /// icmp immediate, that is the target has icmp instructions which can 207 /// compare a register against the immediate without having to materialize 208 /// the immediate into a register. 209 bool isLegalICmpImmediate(int64_t Imm) const override; 210 211 // Handling of atomic RMW instructions. hasLoadLinkedStoreConditional()212 bool hasLoadLinkedStoreConditional() const override { 213 return true; 214 } 215 Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr, 216 AtomicOrdering Ord) const override; 217 Value *emitStoreConditional(IRBuilder<> &Builder, Value *Val, 218 Value *Addr, AtomicOrdering Ord) const override; 219 bool shouldExpandAtomicLoadInIR(LoadInst *LI) const override; 220 bool shouldExpandAtomicStoreInIR(StoreInst *SI) const override; shouldExpandAtomicRMWInIR(AtomicRMWInst * AI)221 AtomicRMWExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) 222 const override { 223 return AtomicRMWExpansionKind::LLSC; 224 } 225 }; 226 } // end namespace llvm 227 228 #endif // Hexagon_ISELLOWERING_H 229