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