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(IRBuilder<> &Builder, Instruction *Inst, 96 AtomicOrdering Ord) const override; 97 Instruction *emitTrailingFence(IRBuilder<> &Builder, Instruction *Inst, 98 AtomicOrdering Ord) const override; 99 TargetLoweringBase::AtomicExpansionKind 100 shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override; 101 102 /// Custom Lower { 103 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 104 unsigned getJumpTableEncoding() const override; 105 const MCExpr *LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI, 106 const MachineBasicBlock *MBB, 107 unsigned Uid, 108 MCContext &Ctx) const override; 109 SDValue getPICJumpTableRelocBase(SDValue Table, 110 SelectionDAG &DAG) const override; 111 // VE doesn't need getPICJumpTableRelocBaseExpr since it is used for only 112 // EK_LabelDifference32. 113 114 SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const; 115 SDValue lowerATOMIC_SWAP(SDValue Op, SelectionDAG &DAG) const; 116 SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 117 SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 118 SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; 119 SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const; 120 SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const; 121 SDValue lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const; 122 SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 123 SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 124 SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; 125 SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const; 126 SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const; 127 SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const; 128 SDValue lowerToTLSGeneralDynamicModel(SDValue Op, SelectionDAG &DAG) const; 129 SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const; 130 SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const; 131 132 SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; 133 SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 134 SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 135 /// } Custom Lower 136 137 /// Replace the results of node with an illegal result 138 /// type with new values built out of custom code. 139 /// 140 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results, 141 SelectionDAG &DAG) const override; 142 143 /// Custom Inserter { 144 MachineBasicBlock * 145 EmitInstrWithCustomInserter(MachineInstr &MI, 146 MachineBasicBlock *MBB) const override; 147 MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI, 148 MachineBasicBlock *MBB) const; 149 MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI, 150 MachineBasicBlock *MBB) const; 151 MachineBasicBlock *emitSjLjDispatchBlock(MachineInstr &MI, 152 MachineBasicBlock *BB) const; 153 154 void setupEntryBlockForSjLj(MachineInstr &MI, MachineBasicBlock *MBB, 155 MachineBasicBlock *DispatchBB, int FI, 156 int Offset) const; 157 // Setup basic block address. 158 Register prepareMBB(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 159 MachineBasicBlock *TargetBB, const DebugLoc &DL) const; 160 // Prepare function/variable address. 161 Register prepareSymbol(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 162 StringRef Symbol, const DebugLoc &DL, bool IsLocal, 163 bool IsCall) const; 164 /// } Custom Inserter 165 166 /// VVP Lowering { 167 SDValue lowerToVVP(SDValue Op, SelectionDAG &DAG) const; 168 /// } VVPLowering 169 170 /// Custom DAGCombine { 171 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; 172 173 SDValue combineTRUNCATE(SDNode *N, DAGCombinerInfo &DCI) const; 174 /// } Custom DAGCombine 175 176 SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const; 177 SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF, 178 SelectionDAG &DAG) const; 179 SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const; 180 181 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; 182 bool isFPImmLegal(const APFloat &Imm, EVT VT, 183 bool ForCodeSize) const override; 184 /// Returns true if the target allows unaligned memory accesses of the 185 /// specified type. 186 bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, unsigned Align, 187 MachineMemOperand::Flags Flags, 188 bool *Fast) const override; 189 190 /// Inline Assembly { 191 192 ConstraintType getConstraintType(StringRef Constraint) const override; 193 std::pair<unsigned, const TargetRegisterClass *> 194 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 195 StringRef Constraint, MVT VT) const override; 196 197 /// } Inline Assembly 198 199 /// Target Optimization { 200 201 // Return lower limit for number of blocks in a jump table. 202 unsigned getMinimumJumpTableEntries() const override; 203 204 // SX-Aurora VE's s/udiv is 5-9 times slower than multiply. 205 bool isIntDivCheap(EVT, AttributeList) const override { return false; } 206 // VE doesn't have rem. 207 bool hasStandaloneRem(EVT) const override { return false; } 208 // VE LDZ instruction returns 64 if the input is zero. 209 bool isCheapToSpeculateCtlz() const override { return true; } 210 // VE LDZ instruction is fast. 211 bool isCtlzFast() const override { return true; } 212 // VE has NND instruction. 213 bool hasAndNot(SDValue Y) const override; 214 215 /// } Target Optimization 216 }; 217 } // namespace llvm 218 219 #endif // VE_ISELLOWERING_H 220