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 /// Convert a DAG integer condition code to a VE ICC condition. 69 inline static VECC::CondCode intCondCode2Icc(ISD::CondCode CC) { 70 switch (CC) { 71 default: 72 llvm_unreachable("Unknown integer condition code!"); 73 case ISD::SETEQ: 74 return VECC::CC_IEQ; 75 case ISD::SETNE: 76 return VECC::CC_INE; 77 case ISD::SETLT: 78 return VECC::CC_IL; 79 case ISD::SETGT: 80 return VECC::CC_IG; 81 case ISD::SETLE: 82 return VECC::CC_ILE; 83 case ISD::SETGE: 84 return VECC::CC_IGE; 85 case ISD::SETULT: 86 return VECC::CC_IL; 87 case ISD::SETULE: 88 return VECC::CC_ILE; 89 case ISD::SETUGT: 90 return VECC::CC_IG; 91 case ISD::SETUGE: 92 return VECC::CC_IGE; 93 } 94 } 95 96 /// Convert a DAG floating point condition code to a VE FCC condition. 97 inline static VECC::CondCode fpCondCode2Fcc(ISD::CondCode CC) { 98 switch (CC) { 99 default: 100 llvm_unreachable("Unknown fp condition code!"); 101 case ISD::SETFALSE: 102 return VECC::CC_AF; 103 case ISD::SETEQ: 104 case ISD::SETOEQ: 105 return VECC::CC_EQ; 106 case ISD::SETNE: 107 case ISD::SETONE: 108 return VECC::CC_NE; 109 case ISD::SETLT: 110 case ISD::SETOLT: 111 return VECC::CC_L; 112 case ISD::SETGT: 113 case ISD::SETOGT: 114 return VECC::CC_G; 115 case ISD::SETLE: 116 case ISD::SETOLE: 117 return VECC::CC_LE; 118 case ISD::SETGE: 119 case ISD::SETOGE: 120 return VECC::CC_GE; 121 case ISD::SETO: 122 return VECC::CC_NUM; 123 case ISD::SETUO: 124 return VECC::CC_NAN; 125 case ISD::SETUEQ: 126 return VECC::CC_EQNAN; 127 case ISD::SETUNE: 128 return VECC::CC_NENAN; 129 case ISD::SETULT: 130 return VECC::CC_LNAN; 131 case ISD::SETUGT: 132 return VECC::CC_GNAN; 133 case ISD::SETULE: 134 return VECC::CC_LENAN; 135 case ISD::SETUGE: 136 return VECC::CC_GENAN; 137 case ISD::SETTRUE: 138 return VECC::CC_AT; 139 } 140 } 141 142 /// getImmVal - get immediate representation of integer value 143 inline static uint64_t getImmVal(const ConstantSDNode *N) { 144 return N->getSExtValue(); 145 } 146 147 /// getFpImmVal - get immediate representation of floating point value 148 inline static uint64_t getFpImmVal(const ConstantFPSDNode *N) { 149 const APInt &Imm = N->getValueAPF().bitcastToAPInt(); 150 uint64_t Val = Imm.getZExtValue(); 151 if (Imm.getBitWidth() == 32) { 152 // Immediate value of float place places at higher bits on VE. 153 Val <<= 32; 154 } 155 return Val; 156 } 157 158 class VECustomDAG; 159 160 class VETargetLowering : public TargetLowering { 161 const VESubtarget *Subtarget; 162 163 void initRegisterClasses(); 164 void initSPUActions(); 165 void initVPUActions(); 166 167 public: 168 VETargetLowering(const TargetMachine &TM, const VESubtarget &STI); 169 170 const char *getTargetNodeName(unsigned Opcode) const override; 171 MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override { 172 return MVT::i32; 173 } 174 175 Register getRegisterByName(const char *RegName, LLT VT, 176 const MachineFunction &MF) const override; 177 178 /// getSetCCResultType - Return the ISD::SETCC ValueType 179 EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, 180 EVT VT) const override; 181 182 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, 183 bool isVarArg, 184 const SmallVectorImpl<ISD::InputArg> &Ins, 185 const SDLoc &dl, SelectionDAG &DAG, 186 SmallVectorImpl<SDValue> &InVals) const override; 187 188 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, 189 SmallVectorImpl<SDValue> &InVals) const override; 190 191 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 192 bool isVarArg, 193 const SmallVectorImpl<ISD::OutputArg> &ArgsFlags, 194 LLVMContext &Context) const override; 195 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 196 const SmallVectorImpl<ISD::OutputArg> &Outs, 197 const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl, 198 SelectionDAG &DAG) const override; 199 200 /// Helper functions for atomic operations. 201 bool shouldInsertFencesForAtomic(const Instruction *I) const override { 202 // VE uses release consistency, so need fence for each atomics. 203 return true; 204 } 205 Instruction *emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, 206 AtomicOrdering Ord) const override; 207 Instruction *emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, 208 AtomicOrdering Ord) const override; 209 TargetLoweringBase::AtomicExpansionKind 210 shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override; 211 ISD::NodeType getExtendForAtomicOps() const override { 212 return ISD::ANY_EXTEND; 213 } 214 215 /// Custom Lower { 216 TargetLoweringBase::LegalizeAction 217 getCustomOperationAction(SDNode &) const override; 218 219 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 220 unsigned getJumpTableEncoding() const override; 221 const MCExpr *LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI, 222 const MachineBasicBlock *MBB, 223 unsigned Uid, 224 MCContext &Ctx) const override; 225 SDValue getPICJumpTableRelocBase(SDValue Table, 226 SelectionDAG &DAG) const override; 227 // VE doesn't need getPICJumpTableRelocBaseExpr since it is used for only 228 // EK_LabelDifference32. 229 230 SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const; 231 SDValue lowerATOMIC_SWAP(SDValue Op, SelectionDAG &DAG) const; 232 SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 233 SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 234 SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; 235 SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const; 236 SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const; 237 SDValue lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const; 238 SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 239 SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 240 SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; 241 SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const; 242 SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const; 243 SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const; 244 SDValue lowerToTLSGeneralDynamicModel(SDValue Op, SelectionDAG &DAG) const; 245 SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const; 246 SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const; 247 248 SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; 249 SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 250 SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 251 /// } Custom Lower 252 253 /// Replace the results of node with an illegal result 254 /// type with new values built out of custom code. 255 /// 256 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results, 257 SelectionDAG &DAG) const override; 258 259 /// Custom Inserter { 260 MachineBasicBlock * 261 EmitInstrWithCustomInserter(MachineInstr &MI, 262 MachineBasicBlock *MBB) const override; 263 MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI, 264 MachineBasicBlock *MBB) const; 265 MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI, 266 MachineBasicBlock *MBB) const; 267 MachineBasicBlock *emitSjLjDispatchBlock(MachineInstr &MI, 268 MachineBasicBlock *BB) const; 269 270 void setupEntryBlockForSjLj(MachineInstr &MI, MachineBasicBlock *MBB, 271 MachineBasicBlock *DispatchBB, int FI, 272 int Offset) const; 273 // Setup basic block address. 274 Register prepareMBB(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 275 MachineBasicBlock *TargetBB, const DebugLoc &DL) const; 276 // Prepare function/variable address. 277 Register prepareSymbol(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 278 StringRef Symbol, const DebugLoc &DL, bool IsLocal, 279 bool IsCall) const; 280 /// } Custom Inserter 281 282 /// VVP Lowering { 283 SDValue lowerToVVP(SDValue Op, SelectionDAG &DAG) const; 284 SDValue lowerVVP_LOAD_STORE(SDValue Op, VECustomDAG &) const; 285 SDValue lowerVVP_GATHER_SCATTER(SDValue Op, VECustomDAG &) const; 286 287 SDValue legalizeInternalVectorOp(SDValue Op, SelectionDAG &DAG) const; 288 SDValue legalizeInternalLoadStoreOp(SDValue Op, VECustomDAG &CDAG) const; 289 SDValue splitVectorOp(SDValue Op, VECustomDAG &CDAG) const; 290 SDValue splitPackedLoadStore(SDValue Op, VECustomDAG &CDAG) const; 291 SDValue legalizePackedAVL(SDValue Op, VECustomDAG &CDAG) const; 292 SDValue splitMaskArithmetic(SDValue Op, SelectionDAG &DAG) const; 293 /// } VVPLowering 294 295 /// Custom DAGCombine { 296 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; 297 298 SDValue combineSelect(SDNode *N, DAGCombinerInfo &DCI) const; 299 SDValue combineSelectCC(SDNode *N, DAGCombinerInfo &DCI) const; 300 SDValue combineTRUNCATE(SDNode *N, DAGCombinerInfo &DCI) const; 301 /// } Custom DAGCombine 302 303 SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const; 304 SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF, 305 SelectionDAG &DAG) const; 306 SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const; 307 308 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; 309 bool isFPImmLegal(const APFloat &Imm, EVT VT, 310 bool ForCodeSize) const override; 311 /// Returns true if the target allows unaligned memory accesses of the 312 /// specified type. 313 bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align A, 314 MachineMemOperand::Flags Flags, 315 unsigned *Fast) const override; 316 317 /// Inline Assembly { 318 319 ConstraintType getConstraintType(StringRef Constraint) const override; 320 std::pair<unsigned, const TargetRegisterClass *> 321 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 322 StringRef Constraint, MVT VT) const override; 323 324 /// } Inline Assembly 325 326 /// Target Optimization { 327 328 // Return lower limit for number of blocks in a jump table. 329 unsigned getMinimumJumpTableEntries() const override; 330 331 // SX-Aurora VE's s/udiv is 5-9 times slower than multiply. 332 bool isIntDivCheap(EVT, AttributeList) const override { return false; } 333 // VE doesn't have rem. 334 bool hasStandaloneRem(EVT) const override { return false; } 335 // VE LDZ instruction returns 64 if the input is zero. 336 bool isCheapToSpeculateCtlz(Type *) const override { return true; } 337 // VE LDZ instruction is fast. 338 bool isCtlzFast() const override { return true; } 339 // VE has NND instruction. 340 bool hasAndNot(SDValue Y) const override; 341 342 /// } Target Optimization 343 }; 344 } // namespace llvm 345 346 #endif // LLVM_LIB_TARGET_VE_VEISELLOWERING_H 347