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