1 //===-- VEISelLowering.h - VE 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 VE uses to lower LLVM code into a 10 // selection DAG. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_LIB_TARGET_VE_VEISELLOWERING_H 15 #define LLVM_LIB_TARGET_VE_VEISELLOWERING_H 16 17 #include "VE.h" 18 #include "llvm/CodeGen/TargetLowering.h" 19 20 namespace llvm { 21 class VESubtarget; 22 23 namespace VEISD { 24 enum NodeType : unsigned { 25 FIRST_NUMBER = ISD::BUILTIN_OP_END, 26 27 CALL, // A call instruction. 28 EH_SJLJ_LONGJMP, // SjLj exception handling longjmp. 29 EH_SJLJ_SETJMP, // SjLj exception handling setjmp. 30 EH_SJLJ_SETUP_DISPATCH, // SjLj exception handling setup_dispatch. 31 GETFUNPLT, // Load function address through %plt insturction. 32 GETTLSADDR, // Load address for TLS access. 33 GETSTACKTOP, // Retrieve address of stack top (first address of 34 // locals and temporaries). 35 GLOBAL_BASE_REG, // Global base reg for PIC. 36 Hi, // Hi/Lo operations, typically on a global address. 37 Lo, // Hi/Lo operations, typically on a global address. 38 MEMBARRIER, // Compiler barrier only; generate a no-op. 39 RET_FLAG, // Return with a flag operand. 40 TS1AM, // A TS1AM instruction used for 1/2 bytes swap. 41 VEC_UNPACK_LO, // unpack the lo v256 slice of a packed v512 vector. 42 VEC_UNPACK_HI, // unpack the hi v256 slice of a packed v512 vector. 43 // 0: v512 vector, 1: AVL 44 VEC_PACK, // pack a lo and a hi vector into one v512 vector 45 // 0: v256 lo vector, 1: v256 hi vector, 2: AVL 46 47 VEC_BROADCAST, // A vector broadcast instruction. 48 // 0: scalar value, 1: VL 49 REPL_I32, 50 REPL_F32, // Replicate subregister to other half. 51 52 // Annotation as a wrapper. LEGALAVL(VL) means that VL refers to 64bit of 53 // data, whereas the raw EVL coming in from VP nodes always refers to number 54 // of elements, regardless of their size. 55 LEGALAVL, 56 57 // VVP_* nodes. 58 #define ADD_VVP_OP(VVP_NAME, ...) VVP_NAME, 59 #include "VVPNodes.def" 60 }; 61 } 62 63 class VECustomDAG; 64 65 class VETargetLowering : public TargetLowering { 66 const VESubtarget *Subtarget; 67 68 void initRegisterClasses(); 69 void initSPUActions(); 70 void initVPUActions(); 71 72 public: 73 VETargetLowering(const TargetMachine &TM, const VESubtarget &STI); 74 75 const char *getTargetNodeName(unsigned Opcode) const override; 76 MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override { 77 return MVT::i32; 78 } 79 80 Register getRegisterByName(const char *RegName, LLT VT, 81 const MachineFunction &MF) const override; 82 83 /// getSetCCResultType - Return the ISD::SETCC ValueType 84 EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, 85 EVT VT) const override; 86 87 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, 88 bool isVarArg, 89 const SmallVectorImpl<ISD::InputArg> &Ins, 90 const SDLoc &dl, SelectionDAG &DAG, 91 SmallVectorImpl<SDValue> &InVals) const override; 92 93 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, 94 SmallVectorImpl<SDValue> &InVals) const override; 95 96 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 97 bool isVarArg, 98 const SmallVectorImpl<ISD::OutputArg> &ArgsFlags, 99 LLVMContext &Context) const override; 100 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 101 const SmallVectorImpl<ISD::OutputArg> &Outs, 102 const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl, 103 SelectionDAG &DAG) const override; 104 105 /// Helper functions for atomic operations. 106 bool shouldInsertFencesForAtomic(const Instruction *I) const override { 107 // VE uses release consistency, so need fence for each atomics. 108 return true; 109 } 110 Instruction *emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, 111 AtomicOrdering Ord) const override; 112 Instruction *emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, 113 AtomicOrdering Ord) const override; 114 TargetLoweringBase::AtomicExpansionKind 115 shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override; 116 ISD::NodeType getExtendForAtomicOps() const override { 117 return ISD::ANY_EXTEND; 118 } 119 120 /// Custom Lower { 121 TargetLoweringBase::LegalizeAction 122 getCustomOperationAction(SDNode &) const override; 123 124 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 125 unsigned getJumpTableEncoding() const override; 126 const MCExpr *LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI, 127 const MachineBasicBlock *MBB, 128 unsigned Uid, 129 MCContext &Ctx) const override; 130 SDValue getPICJumpTableRelocBase(SDValue Table, 131 SelectionDAG &DAG) const override; 132 // VE doesn't need getPICJumpTableRelocBaseExpr since it is used for only 133 // EK_LabelDifference32. 134 135 SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const; 136 SDValue lowerATOMIC_SWAP(SDValue Op, SelectionDAG &DAG) const; 137 SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 138 SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 139 SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; 140 SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const; 141 SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const; 142 SDValue lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const; 143 SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 144 SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 145 SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; 146 SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const; 147 SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const; 148 SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const; 149 SDValue lowerToTLSGeneralDynamicModel(SDValue Op, SelectionDAG &DAG) const; 150 SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const; 151 SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const; 152 153 SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; 154 SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 155 SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 156 /// } Custom Lower 157 158 /// Replace the results of node with an illegal result 159 /// type with new values built out of custom code. 160 /// 161 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results, 162 SelectionDAG &DAG) const override; 163 164 /// Custom Inserter { 165 MachineBasicBlock * 166 EmitInstrWithCustomInserter(MachineInstr &MI, 167 MachineBasicBlock *MBB) const override; 168 MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI, 169 MachineBasicBlock *MBB) const; 170 MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI, 171 MachineBasicBlock *MBB) const; 172 MachineBasicBlock *emitSjLjDispatchBlock(MachineInstr &MI, 173 MachineBasicBlock *BB) const; 174 175 void setupEntryBlockForSjLj(MachineInstr &MI, MachineBasicBlock *MBB, 176 MachineBasicBlock *DispatchBB, int FI, 177 int Offset) const; 178 // Setup basic block address. 179 Register prepareMBB(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 180 MachineBasicBlock *TargetBB, const DebugLoc &DL) const; 181 // Prepare function/variable address. 182 Register prepareSymbol(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 183 StringRef Symbol, const DebugLoc &DL, bool IsLocal, 184 bool IsCall) const; 185 /// } Custom Inserter 186 187 /// VVP Lowering { 188 SDValue lowerToVVP(SDValue Op, SelectionDAG &DAG) const; 189 SDValue lowerVVP_LOAD_STORE(SDValue Op, VECustomDAG &) const; 190 SDValue lowerVVP_GATHER_SCATTER(SDValue Op, VECustomDAG &) const; 191 192 SDValue legalizeInternalVectorOp(SDValue Op, SelectionDAG &DAG) const; 193 SDValue legalizeInternalLoadStoreOp(SDValue Op, VECustomDAG &CDAG) const; 194 SDValue splitVectorOp(SDValue Op, VECustomDAG &CDAG) const; 195 SDValue splitPackedLoadStore(SDValue Op, VECustomDAG &CDAG) const; 196 SDValue legalizePackedAVL(SDValue Op, VECustomDAG &CDAG) const; 197 SDValue splitMaskArithmetic(SDValue Op, SelectionDAG &DAG) const; 198 /// } VVPLowering 199 200 /// Custom DAGCombine { 201 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; 202 203 SDValue combineTRUNCATE(SDNode *N, DAGCombinerInfo &DCI) const; 204 /// } Custom DAGCombine 205 206 SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const; 207 SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF, 208 SelectionDAG &DAG) const; 209 SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const; 210 211 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; 212 bool isFPImmLegal(const APFloat &Imm, EVT VT, 213 bool ForCodeSize) const override; 214 /// Returns true if the target allows unaligned memory accesses of the 215 /// specified type. 216 bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align A, 217 MachineMemOperand::Flags Flags, 218 bool *Fast) const override; 219 220 /// Inline Assembly { 221 222 ConstraintType getConstraintType(StringRef Constraint) const override; 223 std::pair<unsigned, const TargetRegisterClass *> 224 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 225 StringRef Constraint, MVT VT) const override; 226 227 /// } Inline Assembly 228 229 /// Target Optimization { 230 231 // Return lower limit for number of blocks in a jump table. 232 unsigned getMinimumJumpTableEntries() const override; 233 234 // SX-Aurora VE's s/udiv is 5-9 times slower than multiply. 235 bool isIntDivCheap(EVT, AttributeList) const override { return false; } 236 // VE doesn't have rem. 237 bool hasStandaloneRem(EVT) const override { return false; } 238 // VE LDZ instruction returns 64 if the input is zero. 239 bool isCheapToSpeculateCtlz() const override { return true; } 240 // VE LDZ instruction is fast. 241 bool isCtlzFast() const override { return true; } 242 // VE has NND instruction. 243 bool hasAndNot(SDValue Y) const override; 244 245 /// } Target Optimization 246 }; 247 } // namespace llvm 248 249 #endif // LLVM_LIB_TARGET_VE_VEISELLOWERING_H 250