1480093f4SDimitry Andric //===-- VEISelLowering.h - VE DAG Lowering Interface ------------*- C++ -*-===// 2480093f4SDimitry Andric // 3480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6480093f4SDimitry Andric // 7480093f4SDimitry Andric //===----------------------------------------------------------------------===// 8480093f4SDimitry Andric // 9480093f4SDimitry Andric // This file defines the interfaces that VE uses to lower LLVM code into a 10480093f4SDimitry Andric // selection DAG. 11480093f4SDimitry Andric // 12480093f4SDimitry Andric //===----------------------------------------------------------------------===// 13480093f4SDimitry Andric 14480093f4SDimitry Andric #ifndef LLVM_LIB_TARGET_VE_VEISELLOWERING_H 15480093f4SDimitry Andric #define LLVM_LIB_TARGET_VE_VEISELLOWERING_H 16480093f4SDimitry Andric 17480093f4SDimitry Andric #include "VE.h" 18480093f4SDimitry Andric #include "llvm/CodeGen/TargetLowering.h" 19480093f4SDimitry Andric 20480093f4SDimitry Andric namespace llvm { 21480093f4SDimitry Andric class VESubtarget; 22480093f4SDimitry Andric 23480093f4SDimitry Andric namespace VEISD { 24480093f4SDimitry Andric enum NodeType : unsigned { 25480093f4SDimitry Andric FIRST_NUMBER = ISD::BUILTIN_OP_END, 265ffd83dbSDimitry Andric 27*bdd1243dSDimitry Andric CMPI, // Compare between two signed integer values. 28*bdd1243dSDimitry Andric CMPU, // Compare between two unsigned integer values. 29*bdd1243dSDimitry Andric CMPF, // Compare between two floating-point values. 30*bdd1243dSDimitry Andric CMPQ, // Compare between two quad floating-point values. 31*bdd1243dSDimitry Andric CMOV, // Select between two values using the result of comparison. 32*bdd1243dSDimitry Andric 335ffd83dbSDimitry Andric CALL, // A call instruction. 34e8d8bef9SDimitry Andric EH_SJLJ_LONGJMP, // SjLj exception handling longjmp. 35e8d8bef9SDimitry Andric EH_SJLJ_SETJMP, // SjLj exception handling setjmp. 36e8d8bef9SDimitry Andric EH_SJLJ_SETUP_DISPATCH, // SjLj exception handling setup_dispatch. 37e8d8bef9SDimitry Andric GETFUNPLT, // Load function address through %plt insturction. 38e8d8bef9SDimitry Andric GETTLSADDR, // Load address for TLS access. 39e8d8bef9SDimitry Andric GETSTACKTOP, // Retrieve address of stack top (first address of 40e8d8bef9SDimitry Andric // locals and temporaries). 415ffd83dbSDimitry Andric GLOBAL_BASE_REG, // Global base reg for PIC. 42e8d8bef9SDimitry Andric Hi, // Hi/Lo operations, typically on a global address. 43e8d8bef9SDimitry Andric Lo, // Hi/Lo operations, typically on a global address. 44e8d8bef9SDimitry Andric RET_FLAG, // Return with a flag operand. 45e8d8bef9SDimitry Andric TS1AM, // A TS1AM instruction used for 1/2 bytes swap. 4681ad6265SDimitry Andric VEC_UNPACK_LO, // unpack the lo v256 slice of a packed v512 vector. 4781ad6265SDimitry Andric VEC_UNPACK_HI, // unpack the hi v256 slice of a packed v512 vector. 4881ad6265SDimitry Andric // 0: v512 vector, 1: AVL 4981ad6265SDimitry Andric VEC_PACK, // pack a lo and a hi vector into one v512 vector 5081ad6265SDimitry Andric // 0: v256 lo vector, 1: v256 hi vector, 2: AVL 5181ad6265SDimitry Andric 52e8d8bef9SDimitry Andric VEC_BROADCAST, // A vector broadcast instruction. 53e8d8bef9SDimitry Andric // 0: scalar value, 1: VL 5404eeddc0SDimitry Andric REPL_I32, 5504eeddc0SDimitry Andric REPL_F32, // Replicate subregister to other half. 56e8d8bef9SDimitry Andric 5781ad6265SDimitry Andric // Annotation as a wrapper. LEGALAVL(VL) means that VL refers to 64bit of 5881ad6265SDimitry Andric // data, whereas the raw EVL coming in from VP nodes always refers to number 5981ad6265SDimitry Andric // of elements, regardless of their size. 6081ad6265SDimitry Andric LEGALAVL, 6181ad6265SDimitry Andric 62e8d8bef9SDimitry Andric // VVP_* nodes. 63e8d8bef9SDimitry Andric #define ADD_VVP_OP(VVP_NAME, ...) VVP_NAME, 64e8d8bef9SDimitry Andric #include "VVPNodes.def" 65480093f4SDimitry Andric }; 66480093f4SDimitry Andric } 67480093f4SDimitry Andric 6881ad6265SDimitry Andric class VECustomDAG; 6981ad6265SDimitry Andric 70480093f4SDimitry Andric class VETargetLowering : public TargetLowering { 71480093f4SDimitry Andric const VESubtarget *Subtarget; 72480093f4SDimitry Andric 73e8d8bef9SDimitry Andric void initRegisterClasses(); 74e8d8bef9SDimitry Andric void initSPUActions(); 75e8d8bef9SDimitry Andric void initVPUActions(); 76e8d8bef9SDimitry Andric 77480093f4SDimitry Andric public: 78480093f4SDimitry Andric VETargetLowering(const TargetMachine &TM, const VESubtarget &STI); 79480093f4SDimitry Andric 80480093f4SDimitry Andric const char *getTargetNodeName(unsigned Opcode) const override; 815ffd83dbSDimitry Andric MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override { 825ffd83dbSDimitry Andric return MVT::i32; 835ffd83dbSDimitry Andric } 84480093f4SDimitry Andric 85480093f4SDimitry Andric Register getRegisterByName(const char *RegName, LLT VT, 86480093f4SDimitry Andric const MachineFunction &MF) const override; 87480093f4SDimitry Andric 88480093f4SDimitry Andric /// getSetCCResultType - Return the ISD::SETCC ValueType 89480093f4SDimitry Andric EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, 90480093f4SDimitry Andric EVT VT) const override; 91480093f4SDimitry Andric 92480093f4SDimitry Andric SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, 93480093f4SDimitry Andric bool isVarArg, 94480093f4SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, 95480093f4SDimitry Andric const SDLoc &dl, SelectionDAG &DAG, 96480093f4SDimitry Andric SmallVectorImpl<SDValue> &InVals) const override; 97480093f4SDimitry Andric 985ffd83dbSDimitry Andric SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, 995ffd83dbSDimitry Andric SmallVectorImpl<SDValue> &InVals) const override; 1005ffd83dbSDimitry Andric 101480093f4SDimitry Andric bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 102480093f4SDimitry Andric bool isVarArg, 103480093f4SDimitry Andric const SmallVectorImpl<ISD::OutputArg> &ArgsFlags, 104480093f4SDimitry Andric LLVMContext &Context) const override; 105480093f4SDimitry Andric SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 106480093f4SDimitry Andric const SmallVectorImpl<ISD::OutputArg> &Outs, 107480093f4SDimitry Andric const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl, 108480093f4SDimitry Andric SelectionDAG &DAG) const override; 1095ffd83dbSDimitry Andric 110e8d8bef9SDimitry Andric /// Helper functions for atomic operations. 111e8d8bef9SDimitry Andric bool shouldInsertFencesForAtomic(const Instruction *I) const override { 112e8d8bef9SDimitry Andric // VE uses release consistency, so need fence for each atomics. 113e8d8bef9SDimitry Andric return true; 114e8d8bef9SDimitry Andric } 115fe6060f1SDimitry Andric Instruction *emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, 116e8d8bef9SDimitry Andric AtomicOrdering Ord) const override; 117fe6060f1SDimitry Andric Instruction *emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, 118e8d8bef9SDimitry Andric AtomicOrdering Ord) const override; 119e8d8bef9SDimitry Andric TargetLoweringBase::AtomicExpansionKind 120e8d8bef9SDimitry Andric shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override; 121fe6060f1SDimitry Andric ISD::NodeType getExtendForAtomicOps() const override { 122fe6060f1SDimitry Andric return ISD::ANY_EXTEND; 123fe6060f1SDimitry Andric } 124e8d8bef9SDimitry Andric 1255ffd83dbSDimitry Andric /// Custom Lower { 12681ad6265SDimitry Andric TargetLoweringBase::LegalizeAction 12781ad6265SDimitry Andric getCustomOperationAction(SDNode &) const override; 12881ad6265SDimitry Andric 1295ffd83dbSDimitry Andric SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 130e8d8bef9SDimitry Andric unsigned getJumpTableEncoding() const override; 131e8d8bef9SDimitry Andric const MCExpr *LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI, 132e8d8bef9SDimitry Andric const MachineBasicBlock *MBB, 133e8d8bef9SDimitry Andric unsigned Uid, 134e8d8bef9SDimitry Andric MCContext &Ctx) const override; 135e8d8bef9SDimitry Andric SDValue getPICJumpTableRelocBase(SDValue Table, 136e8d8bef9SDimitry Andric SelectionDAG &DAG) const override; 137e8d8bef9SDimitry Andric // VE doesn't need getPICJumpTableRelocBaseExpr since it is used for only 138e8d8bef9SDimitry Andric // EK_LabelDifference32. 1395ffd83dbSDimitry Andric 140e8d8bef9SDimitry Andric SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const; 141e8d8bef9SDimitry Andric SDValue lowerATOMIC_SWAP(SDValue Op, SelectionDAG &DAG) const; 142e8d8bef9SDimitry Andric SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 143e8d8bef9SDimitry Andric SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 1445ffd83dbSDimitry Andric SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; 145e8d8bef9SDimitry Andric SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const; 146e8d8bef9SDimitry Andric SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const; 147e8d8bef9SDimitry Andric SDValue lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const; 148e8d8bef9SDimitry Andric SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 149e8d8bef9SDimitry Andric SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 150e8d8bef9SDimitry Andric SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; 151e8d8bef9SDimitry Andric SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const; 152e8d8bef9SDimitry Andric SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const; 153e8d8bef9SDimitry Andric SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const; 154e8d8bef9SDimitry Andric SDValue lowerToTLSGeneralDynamicModel(SDValue Op, SelectionDAG &DAG) const; 155e8d8bef9SDimitry Andric SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const; 156e8d8bef9SDimitry Andric SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const; 157e8d8bef9SDimitry Andric 158e8d8bef9SDimitry Andric SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; 159e8d8bef9SDimitry Andric SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 160e8d8bef9SDimitry Andric SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 1615ffd83dbSDimitry Andric /// } Custom Lower 1625ffd83dbSDimitry Andric 163e8d8bef9SDimitry Andric /// Replace the results of node with an illegal result 164e8d8bef9SDimitry Andric /// type with new values built out of custom code. 165e8d8bef9SDimitry Andric /// 166e8d8bef9SDimitry Andric void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results, 167e8d8bef9SDimitry Andric SelectionDAG &DAG) const override; 168e8d8bef9SDimitry Andric 169e8d8bef9SDimitry Andric /// Custom Inserter { 170e8d8bef9SDimitry Andric MachineBasicBlock * 171e8d8bef9SDimitry Andric EmitInstrWithCustomInserter(MachineInstr &MI, 172e8d8bef9SDimitry Andric MachineBasicBlock *MBB) const override; 173e8d8bef9SDimitry Andric MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI, 174e8d8bef9SDimitry Andric MachineBasicBlock *MBB) const; 175e8d8bef9SDimitry Andric MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI, 176e8d8bef9SDimitry Andric MachineBasicBlock *MBB) const; 177e8d8bef9SDimitry Andric MachineBasicBlock *emitSjLjDispatchBlock(MachineInstr &MI, 178e8d8bef9SDimitry Andric MachineBasicBlock *BB) const; 179e8d8bef9SDimitry Andric 180e8d8bef9SDimitry Andric void setupEntryBlockForSjLj(MachineInstr &MI, MachineBasicBlock *MBB, 181e8d8bef9SDimitry Andric MachineBasicBlock *DispatchBB, int FI, 182e8d8bef9SDimitry Andric int Offset) const; 183e8d8bef9SDimitry Andric // Setup basic block address. 184e8d8bef9SDimitry Andric Register prepareMBB(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 185e8d8bef9SDimitry Andric MachineBasicBlock *TargetBB, const DebugLoc &DL) const; 186e8d8bef9SDimitry Andric // Prepare function/variable address. 187e8d8bef9SDimitry Andric Register prepareSymbol(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 188e8d8bef9SDimitry Andric StringRef Symbol, const DebugLoc &DL, bool IsLocal, 189e8d8bef9SDimitry Andric bool IsCall) const; 190e8d8bef9SDimitry Andric /// } Custom Inserter 191e8d8bef9SDimitry Andric 192e8d8bef9SDimitry Andric /// VVP Lowering { 193e8d8bef9SDimitry Andric SDValue lowerToVVP(SDValue Op, SelectionDAG &DAG) const; 19481ad6265SDimitry Andric SDValue lowerVVP_LOAD_STORE(SDValue Op, VECustomDAG &) const; 19581ad6265SDimitry Andric SDValue lowerVVP_GATHER_SCATTER(SDValue Op, VECustomDAG &) const; 19681ad6265SDimitry Andric 19781ad6265SDimitry Andric SDValue legalizeInternalVectorOp(SDValue Op, SelectionDAG &DAG) const; 19881ad6265SDimitry Andric SDValue legalizeInternalLoadStoreOp(SDValue Op, VECustomDAG &CDAG) const; 19981ad6265SDimitry Andric SDValue splitVectorOp(SDValue Op, VECustomDAG &CDAG) const; 20081ad6265SDimitry Andric SDValue splitPackedLoadStore(SDValue Op, VECustomDAG &CDAG) const; 20181ad6265SDimitry Andric SDValue legalizePackedAVL(SDValue Op, VECustomDAG &CDAG) const; 20281ad6265SDimitry Andric SDValue splitMaskArithmetic(SDValue Op, SelectionDAG &DAG) const; 203e8d8bef9SDimitry Andric /// } VVPLowering 204e8d8bef9SDimitry Andric 205e8d8bef9SDimitry Andric /// Custom DAGCombine { 206e8d8bef9SDimitry Andric SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; 207e8d8bef9SDimitry Andric 208*bdd1243dSDimitry Andric SDValue combineSelect(SDNode *N, DAGCombinerInfo &DCI) const; 209*bdd1243dSDimitry Andric SDValue combineSelectCC(SDNode *N, DAGCombinerInfo &DCI) const; 210e8d8bef9SDimitry Andric SDValue combineTRUNCATE(SDNode *N, DAGCombinerInfo &DCI) const; 211e8d8bef9SDimitry Andric /// } Custom DAGCombine 212e8d8bef9SDimitry Andric 2135ffd83dbSDimitry Andric SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const; 2145ffd83dbSDimitry Andric SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF, 2155ffd83dbSDimitry Andric SelectionDAG &DAG) const; 2165ffd83dbSDimitry Andric SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const; 2175ffd83dbSDimitry Andric 218e8d8bef9SDimitry Andric bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; 2195ffd83dbSDimitry Andric bool isFPImmLegal(const APFloat &Imm, EVT VT, 2205ffd83dbSDimitry Andric bool ForCodeSize) const override; 2215ffd83dbSDimitry Andric /// Returns true if the target allows unaligned memory accesses of the 2225ffd83dbSDimitry Andric /// specified type. 223fe6060f1SDimitry Andric bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align A, 2245ffd83dbSDimitry Andric MachineMemOperand::Flags Flags, 225*bdd1243dSDimitry Andric unsigned *Fast) const override; 2265ffd83dbSDimitry Andric 227e8d8bef9SDimitry Andric /// Inline Assembly { 2285ffd83dbSDimitry Andric 229e8d8bef9SDimitry Andric ConstraintType getConstraintType(StringRef Constraint) const override; 230e8d8bef9SDimitry Andric std::pair<unsigned, const TargetRegisterClass *> 231e8d8bef9SDimitry Andric getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 232e8d8bef9SDimitry Andric StringRef Constraint, MVT VT) const override; 233e8d8bef9SDimitry Andric 234e8d8bef9SDimitry Andric /// } Inline Assembly 235e8d8bef9SDimitry Andric 236e8d8bef9SDimitry Andric /// Target Optimization { 237e8d8bef9SDimitry Andric 238e8d8bef9SDimitry Andric // Return lower limit for number of blocks in a jump table. 239e8d8bef9SDimitry Andric unsigned getMinimumJumpTableEntries() const override; 240e8d8bef9SDimitry Andric 241e8d8bef9SDimitry Andric // SX-Aurora VE's s/udiv is 5-9 times slower than multiply. 242e8d8bef9SDimitry Andric bool isIntDivCheap(EVT, AttributeList) const override { return false; } 243e8d8bef9SDimitry Andric // VE doesn't have rem. 244e8d8bef9SDimitry Andric bool hasStandaloneRem(EVT) const override { return false; } 245e8d8bef9SDimitry Andric // VE LDZ instruction returns 64 if the input is zero. 246*bdd1243dSDimitry Andric bool isCheapToSpeculateCtlz(Type *) const override { return true; } 247e8d8bef9SDimitry Andric // VE LDZ instruction is fast. 248e8d8bef9SDimitry Andric bool isCtlzFast() const override { return true; } 249e8d8bef9SDimitry Andric // VE has NND instruction. 2505ffd83dbSDimitry Andric bool hasAndNot(SDValue Y) const override; 251e8d8bef9SDimitry Andric 252e8d8bef9SDimitry Andric /// } Target Optimization 253480093f4SDimitry Andric }; 254480093f4SDimitry Andric } // namespace llvm 255480093f4SDimitry Andric 25604eeddc0SDimitry Andric #endif // LLVM_LIB_TARGET_VE_VEISELLOWERING_H 257