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_BROADCAST, // A vector broadcast instruction. 42 // 0: scalar value, 1: VL 43 44 // VVP_* nodes. 45 #define ADD_VVP_OP(VVP_NAME, ...) VVP_NAME, 46 #include "VVPNodes.def" 47 }; 48 } 49 50 class VETargetLowering : public TargetLowering { 51 const VESubtarget *Subtarget; 52 53 void initRegisterClasses(); 54 void initSPUActions(); 55 void initVPUActions(); 56 57 public: 58 VETargetLowering(const TargetMachine &TM, const VESubtarget &STI); 59 60 const char *getTargetNodeName(unsigned Opcode) const override; 61 MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override { 62 return MVT::i32; 63 } 64 65 Register getRegisterByName(const char *RegName, LLT VT, 66 const MachineFunction &MF) const override; 67 68 /// getSetCCResultType - Return the ISD::SETCC ValueType 69 EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, 70 EVT VT) const override; 71 72 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, 73 bool isVarArg, 74 const SmallVectorImpl<ISD::InputArg> &Ins, 75 const SDLoc &dl, SelectionDAG &DAG, 76 SmallVectorImpl<SDValue> &InVals) const override; 77 78 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, 79 SmallVectorImpl<SDValue> &InVals) const override; 80 81 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 82 bool isVarArg, 83 const SmallVectorImpl<ISD::OutputArg> &ArgsFlags, 84 LLVMContext &Context) const override; 85 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 86 const SmallVectorImpl<ISD::OutputArg> &Outs, 87 const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl, 88 SelectionDAG &DAG) const override; 89 90 /// Helper functions for atomic operations. 91 bool shouldInsertFencesForAtomic(const Instruction *I) const override { 92 // VE uses release consistency, so need fence for each atomics. 93 return true; 94 } 95 Instruction *emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, 96 AtomicOrdering Ord) const override; 97 Instruction *emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, 98 AtomicOrdering Ord) const override; 99 TargetLoweringBase::AtomicExpansionKind 100 shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override; 101 ISD::NodeType getExtendForAtomicOps() const override { 102 return ISD::ANY_EXTEND; 103 } 104 105 /// Custom Lower { 106 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 107 unsigned getJumpTableEncoding() const override; 108 const MCExpr *LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI, 109 const MachineBasicBlock *MBB, 110 unsigned Uid, 111 MCContext &Ctx) const override; 112 SDValue getPICJumpTableRelocBase(SDValue Table, 113 SelectionDAG &DAG) const override; 114 // VE doesn't need getPICJumpTableRelocBaseExpr since it is used for only 115 // EK_LabelDifference32. 116 117 SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const; 118 SDValue lowerATOMIC_SWAP(SDValue Op, SelectionDAG &DAG) const; 119 SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 120 SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 121 SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; 122 SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const; 123 SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const; 124 SDValue lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const; 125 SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 126 SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 127 SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; 128 SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const; 129 SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const; 130 SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const; 131 SDValue lowerToTLSGeneralDynamicModel(SDValue Op, SelectionDAG &DAG) const; 132 SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const; 133 SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const; 134 135 SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; 136 SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 137 SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 138 /// } Custom Lower 139 140 /// Replace the results of node with an illegal result 141 /// type with new values built out of custom code. 142 /// 143 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results, 144 SelectionDAG &DAG) const override; 145 146 /// Custom Inserter { 147 MachineBasicBlock * 148 EmitInstrWithCustomInserter(MachineInstr &MI, 149 MachineBasicBlock *MBB) const override; 150 MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI, 151 MachineBasicBlock *MBB) const; 152 MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI, 153 MachineBasicBlock *MBB) const; 154 MachineBasicBlock *emitSjLjDispatchBlock(MachineInstr &MI, 155 MachineBasicBlock *BB) const; 156 157 void setupEntryBlockForSjLj(MachineInstr &MI, MachineBasicBlock *MBB, 158 MachineBasicBlock *DispatchBB, int FI, 159 int Offset) const; 160 // Setup basic block address. 161 Register prepareMBB(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 162 MachineBasicBlock *TargetBB, const DebugLoc &DL) const; 163 // Prepare function/variable address. 164 Register prepareSymbol(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 165 StringRef Symbol, const DebugLoc &DL, bool IsLocal, 166 bool IsCall) const; 167 /// } Custom Inserter 168 169 /// VVP Lowering { 170 SDValue lowerToVVP(SDValue Op, SelectionDAG &DAG) const; 171 /// } VVPLowering 172 173 /// Custom DAGCombine { 174 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; 175 176 SDValue combineTRUNCATE(SDNode *N, DAGCombinerInfo &DCI) const; 177 /// } Custom DAGCombine 178 179 SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const; 180 SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF, 181 SelectionDAG &DAG) const; 182 SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const; 183 184 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; 185 bool isFPImmLegal(const APFloat &Imm, EVT VT, 186 bool ForCodeSize) const override; 187 /// Returns true if the target allows unaligned memory accesses of the 188 /// specified type. 189 bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align A, 190 MachineMemOperand::Flags Flags, 191 bool *Fast) const override; 192 193 /// Inline Assembly { 194 195 ConstraintType getConstraintType(StringRef Constraint) const override; 196 std::pair<unsigned, const TargetRegisterClass *> 197 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 198 StringRef Constraint, MVT VT) const override; 199 200 /// } Inline Assembly 201 202 /// Target Optimization { 203 204 // Return lower limit for number of blocks in a jump table. 205 unsigned getMinimumJumpTableEntries() const override; 206 207 // SX-Aurora VE's s/udiv is 5-9 times slower than multiply. 208 bool isIntDivCheap(EVT, AttributeList) const override { return false; } 209 // VE doesn't have rem. 210 bool hasStandaloneRem(EVT) const override { return false; } 211 // VE LDZ instruction returns 64 if the input is zero. 212 bool isCheapToSpeculateCtlz() const override { return true; } 213 // VE LDZ instruction is fast. 214 bool isCtlzFast() const override { return true; } 215 // VE has NND instruction. 216 bool hasAndNot(SDValue Y) const override; 217 218 /// } Target Optimization 219 }; 220 } // namespace llvm 221 222 #endif // VE_ISELLOWERING_H 223