Add gfx950 mfma instructions to ROCDL dialect (#123361)
[llvm-project.git] / llvm / lib / Target / VE / VEISelLowering.h
blob04274b14baa1f34bacfa653372f3f80343129474
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.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_LIB_TARGET_VE_VEISELLOWERING_H
15 #define LLVM_LIB_TARGET_VE_VEISELLOWERING_H
17 #include "VE.h"
18 #include "llvm/CodeGen/TargetLowering.h"
20 namespace llvm {
21 class VESubtarget;
23 namespace VEISD {
24 enum NodeType : unsigned {
25 FIRST_NUMBER = ISD::BUILTIN_OP_END,
27 CMPI, // Compare between two signed integer values.
28 CMPU, // Compare between two unsigned integer values.
29 CMPF, // Compare between two floating-point values.
30 CMPQ, // Compare between two quad floating-point values.
31 CMOV, // Select between two values using the result of comparison.
33 CALL, // A call instruction.
34 EH_SJLJ_LONGJMP, // SjLj exception handling longjmp.
35 EH_SJLJ_SETJMP, // SjLj exception handling setjmp.
36 EH_SJLJ_SETUP_DISPATCH, // SjLj exception handling setup_dispatch.
37 GETFUNPLT, // Load function address through %plt insturction.
38 GETTLSADDR, // Load address for TLS access.
39 GETSTACKTOP, // Retrieve address of stack top (first address of
40 // locals and temporaries).
41 GLOBAL_BASE_REG, // Global base reg for PIC.
42 Hi, // Hi/Lo operations, typically on a global address.
43 Lo, // Hi/Lo operations, typically on a global address.
44 RET_GLUE, // Return with a flag operand.
45 TS1AM, // A TS1AM instruction used for 1/2 bytes swap.
46 VEC_UNPACK_LO, // unpack the lo v256 slice of a packed v512 vector.
47 VEC_UNPACK_HI, // unpack the hi v256 slice of a packed v512 vector.
48 // 0: v512 vector, 1: AVL
49 VEC_PACK, // pack a lo and a hi vector into one v512 vector
50 // 0: v256 lo vector, 1: v256 hi vector, 2: AVL
52 VEC_BROADCAST, // A vector broadcast instruction.
53 // 0: scalar value, 1: VL
54 REPL_I32,
55 REPL_F32, // Replicate subregister to other half.
57 // Annotation as a wrapper. LEGALAVL(VL) means that VL refers to 64bit of
58 // data, whereas the raw EVL coming in from VP nodes always refers to number
59 // of elements, regardless of their size.
60 LEGALAVL,
62 // VVP_* nodes.
63 #define ADD_VVP_OP(VVP_NAME, ...) VVP_NAME,
64 #include "VVPNodes.def"
68 /// Convert a DAG integer condition code to a VE ICC condition.
69 inline static VECC::CondCode intCondCode2Icc(ISD::CondCode CC) {
70 switch (CC) {
71 default:
72 llvm_unreachable("Unknown integer condition code!");
73 case ISD::SETEQ:
74 return VECC::CC_IEQ;
75 case ISD::SETNE:
76 return VECC::CC_INE;
77 case ISD::SETLT:
78 return VECC::CC_IL;
79 case ISD::SETGT:
80 return VECC::CC_IG;
81 case ISD::SETLE:
82 return VECC::CC_ILE;
83 case ISD::SETGE:
84 return VECC::CC_IGE;
85 case ISD::SETULT:
86 return VECC::CC_IL;
87 case ISD::SETULE:
88 return VECC::CC_ILE;
89 case ISD::SETUGT:
90 return VECC::CC_IG;
91 case ISD::SETUGE:
92 return VECC::CC_IGE;
96 /// Convert a DAG floating point condition code to a VE FCC condition.
97 inline static VECC::CondCode fpCondCode2Fcc(ISD::CondCode CC) {
98 switch (CC) {
99 default:
100 llvm_unreachable("Unknown fp condition code!");
101 case ISD::SETFALSE:
102 return VECC::CC_AF;
103 case ISD::SETEQ:
104 case ISD::SETOEQ:
105 return VECC::CC_EQ;
106 case ISD::SETNE:
107 case ISD::SETONE:
108 return VECC::CC_NE;
109 case ISD::SETLT:
110 case ISD::SETOLT:
111 return VECC::CC_L;
112 case ISD::SETGT:
113 case ISD::SETOGT:
114 return VECC::CC_G;
115 case ISD::SETLE:
116 case ISD::SETOLE:
117 return VECC::CC_LE;
118 case ISD::SETGE:
119 case ISD::SETOGE:
120 return VECC::CC_GE;
121 case ISD::SETO:
122 return VECC::CC_NUM;
123 case ISD::SETUO:
124 return VECC::CC_NAN;
125 case ISD::SETUEQ:
126 return VECC::CC_EQNAN;
127 case ISD::SETUNE:
128 return VECC::CC_NENAN;
129 case ISD::SETULT:
130 return VECC::CC_LNAN;
131 case ISD::SETUGT:
132 return VECC::CC_GNAN;
133 case ISD::SETULE:
134 return VECC::CC_LENAN;
135 case ISD::SETUGE:
136 return VECC::CC_GENAN;
137 case ISD::SETTRUE:
138 return VECC::CC_AT;
142 /// getImmVal - get immediate representation of integer value
143 inline static uint64_t getImmVal(const ConstantSDNode *N) {
144 return N->getSExtValue();
147 /// getFpImmVal - get immediate representation of floating point value
148 inline static uint64_t getFpImmVal(const ConstantFPSDNode *N) {
149 const APInt &Imm = N->getValueAPF().bitcastToAPInt();
150 uint64_t Val = Imm.getZExtValue();
151 if (Imm.getBitWidth() == 32) {
152 // Immediate value of float place places at higher bits on VE.
153 Val <<= 32;
155 return Val;
158 class VECustomDAG;
160 class VETargetLowering : public TargetLowering {
161 const VESubtarget *Subtarget;
163 void initRegisterClasses();
164 void initSPUActions();
165 void initVPUActions();
167 public:
168 VETargetLowering(const TargetMachine &TM, const VESubtarget &STI);
170 const char *getTargetNodeName(unsigned Opcode) const override;
171 MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override {
172 return MVT::i32;
175 Register getRegisterByName(const char *RegName, LLT VT,
176 const MachineFunction &MF) const override;
178 /// getSetCCResultType - Return the ISD::SETCC ValueType
179 EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
180 EVT VT) const override;
182 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
183 bool isVarArg,
184 const SmallVectorImpl<ISD::InputArg> &Ins,
185 const SDLoc &dl, SelectionDAG &DAG,
186 SmallVectorImpl<SDValue> &InVals) const override;
188 SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
189 SmallVectorImpl<SDValue> &InVals) const override;
191 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
192 bool isVarArg,
193 const SmallVectorImpl<ISD::OutputArg> &ArgsFlags,
194 LLVMContext &Context,
195 const Type *RetTy) const override;
196 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
197 const SmallVectorImpl<ISD::OutputArg> &Outs,
198 const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl,
199 SelectionDAG &DAG) const override;
201 /// Helper functions for atomic operations.
202 bool shouldInsertFencesForAtomic(const Instruction *I) const override {
203 // VE uses release consistency, so need fence for each atomics.
204 return true;
206 Instruction *emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst,
207 AtomicOrdering Ord) const override;
208 Instruction *emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst,
209 AtomicOrdering Ord) const override;
210 TargetLoweringBase::AtomicExpansionKind
211 shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override;
212 ISD::NodeType getExtendForAtomicOps() const override {
213 return ISD::ANY_EXTEND;
216 /// Custom Lower {
217 TargetLoweringBase::LegalizeAction
218 getCustomOperationAction(SDNode &) const override;
220 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
221 unsigned getJumpTableEncoding() const override;
222 const MCExpr *LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI,
223 const MachineBasicBlock *MBB,
224 unsigned Uid,
225 MCContext &Ctx) const override;
226 SDValue getPICJumpTableRelocBase(SDValue Table,
227 SelectionDAG &DAG) const override;
228 // VE doesn't need getPICJumpTableRelocBaseExpr since it is used for only
229 // EK_LabelDifference32.
231 SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const;
232 SDValue lowerATOMIC_SWAP(SDValue Op, SelectionDAG &DAG) const;
233 SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
234 SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
235 SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
236 SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;
237 SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;
238 SDValue lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const;
239 SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
240 SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
241 SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
242 SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
243 SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const;
244 SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const;
245 SDValue lowerToTLSGeneralDynamicModel(SDValue Op, SelectionDAG &DAG) const;
246 SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
247 SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const;
249 SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
250 SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
251 SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
252 /// } Custom Lower
254 /// Replace the results of node with an illegal result
255 /// type with new values built out of custom code.
257 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
258 SelectionDAG &DAG) const override;
260 /// Custom Inserter {
261 MachineBasicBlock *
262 EmitInstrWithCustomInserter(MachineInstr &MI,
263 MachineBasicBlock *MBB) const override;
264 MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI,
265 MachineBasicBlock *MBB) const;
266 MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI,
267 MachineBasicBlock *MBB) const;
268 MachineBasicBlock *emitSjLjDispatchBlock(MachineInstr &MI,
269 MachineBasicBlock *BB) const;
271 void setupEntryBlockForSjLj(MachineInstr &MI, MachineBasicBlock *MBB,
272 MachineBasicBlock *DispatchBB, int FI,
273 int Offset) const;
274 // Setup basic block address.
275 Register prepareMBB(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
276 MachineBasicBlock *TargetBB, const DebugLoc &DL) const;
277 // Prepare function/variable address.
278 Register prepareSymbol(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
279 StringRef Symbol, const DebugLoc &DL, bool IsLocal,
280 bool IsCall) const;
281 /// } Custom Inserter
283 /// VVP Lowering {
284 SDValue lowerToVVP(SDValue Op, SelectionDAG &DAG) const;
285 SDValue lowerVVP_LOAD_STORE(SDValue Op, VECustomDAG &) const;
286 SDValue lowerVVP_GATHER_SCATTER(SDValue Op, VECustomDAG &) const;
288 SDValue legalizeInternalVectorOp(SDValue Op, SelectionDAG &DAG) const;
289 SDValue legalizeInternalLoadStoreOp(SDValue Op, VECustomDAG &CDAG) const;
290 SDValue splitVectorOp(SDValue Op, VECustomDAG &CDAG) const;
291 SDValue splitPackedLoadStore(SDValue Op, VECustomDAG &CDAG) const;
292 SDValue legalizePackedAVL(SDValue Op, VECustomDAG &CDAG) const;
293 SDValue splitMaskArithmetic(SDValue Op, SelectionDAG &DAG) const;
294 /// } VVPLowering
296 /// Custom DAGCombine {
297 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
299 SDValue combineSelect(SDNode *N, DAGCombinerInfo &DCI) const;
300 SDValue combineSelectCC(SDNode *N, DAGCombinerInfo &DCI) const;
301 SDValue combineTRUNCATE(SDNode *N, DAGCombinerInfo &DCI) const;
302 /// } Custom DAGCombine
304 SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const;
305 SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF,
306 SelectionDAG &DAG) const;
307 SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const;
309 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
310 bool isFPImmLegal(const APFloat &Imm, EVT VT,
311 bool ForCodeSize) const override;
312 /// Returns true if the target allows unaligned memory accesses of the
313 /// specified type.
314 bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align A,
315 MachineMemOperand::Flags Flags,
316 unsigned *Fast) const override;
318 /// Inline Assembly {
320 ConstraintType getConstraintType(StringRef Constraint) const override;
321 std::pair<unsigned, const TargetRegisterClass *>
322 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
323 StringRef Constraint, MVT VT) const override;
325 /// } Inline Assembly
327 /// Target Optimization {
329 // Return lower limit for number of blocks in a jump table.
330 unsigned getMinimumJumpTableEntries() const override;
332 // SX-Aurora VE's s/udiv is 5-9 times slower than multiply.
333 bool isIntDivCheap(EVT, AttributeList) const override { return false; }
334 // VE doesn't have rem.
335 bool hasStandaloneRem(EVT) const override { return false; }
336 // VE LDZ instruction returns 64 if the input is zero.
337 bool isCheapToSpeculateCtlz(Type *) const override { return true; }
338 // VE LDZ instruction is fast.
339 bool isCtlzFast() const override { return true; }
340 // VE has NND instruction.
341 bool hasAndNot(SDValue Y) const override;
343 /// } Target Optimization
345 } // namespace llvm
347 #endif // LLVM_LIB_TARGET_VE_VEISELLOWERING_H