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