Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/VE/VEISelLowering.h
35269 views
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
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.
32
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
51
52
VEC_BROADCAST, // A vector broadcast instruction.
53
// 0: scalar value, 1: VL
54
REPL_I32,
55
REPL_F32, // Replicate subregister to other half.
56
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,
61
62
// VVP_* nodes.
63
#define ADD_VVP_OP(VVP_NAME, ...) VVP_NAME,
64
#include "VVPNodes.def"
65
};
66
}
67
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;
93
}
94
}
95
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;
139
}
140
}
141
142
/// getImmVal - get immediate representation of integer value
143
inline static uint64_t getImmVal(const ConstantSDNode *N) {
144
return N->getSExtValue();
145
}
146
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;
154
}
155
return Val;
156
}
157
158
class VECustomDAG;
159
160
class VETargetLowering : public TargetLowering {
161
const VESubtarget *Subtarget;
162
163
void initRegisterClasses();
164
void initSPUActions();
165
void initVPUActions();
166
167
public:
168
VETargetLowering(const TargetMachine &TM, const VESubtarget &STI);
169
170
const char *getTargetNodeName(unsigned Opcode) const override;
171
MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override {
172
return MVT::i32;
173
}
174
175
Register getRegisterByName(const char *RegName, LLT VT,
176
const MachineFunction &MF) const override;
177
178
/// getSetCCResultType - Return the ISD::SETCC ValueType
179
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
180
EVT VT) const override;
181
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;
187
188
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
189
SmallVectorImpl<SDValue> &InVals) const override;
190
191
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
192
bool isVarArg,
193
const SmallVectorImpl<ISD::OutputArg> &ArgsFlags,
194
LLVMContext &Context) const override;
195
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
196
const SmallVectorImpl<ISD::OutputArg> &Outs,
197
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl,
198
SelectionDAG &DAG) const override;
199
200
/// Helper functions for atomic operations.
201
bool shouldInsertFencesForAtomic(const Instruction *I) const override {
202
// VE uses release consistency, so need fence for each atomics.
203
return true;
204
}
205
Instruction *emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst,
206
AtomicOrdering Ord) const override;
207
Instruction *emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst,
208
AtomicOrdering Ord) const override;
209
TargetLoweringBase::AtomicExpansionKind
210
shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override;
211
ISD::NodeType getExtendForAtomicOps() const override {
212
return ISD::ANY_EXTEND;
213
}
214
215
/// Custom Lower {
216
TargetLoweringBase::LegalizeAction
217
getCustomOperationAction(SDNode &) const override;
218
219
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
220
unsigned getJumpTableEncoding() const override;
221
const MCExpr *LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI,
222
const MachineBasicBlock *MBB,
223
unsigned Uid,
224
MCContext &Ctx) const override;
225
SDValue getPICJumpTableRelocBase(SDValue Table,
226
SelectionDAG &DAG) const override;
227
// VE doesn't need getPICJumpTableRelocBaseExpr since it is used for only
228
// EK_LabelDifference32.
229
230
SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const;
231
SDValue lowerATOMIC_SWAP(SDValue Op, SelectionDAG &DAG) const;
232
SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
233
SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
234
SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
235
SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;
236
SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;
237
SDValue lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const;
238
SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
239
SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
240
SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
241
SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
242
SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const;
243
SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const;
244
SDValue lowerToTLSGeneralDynamicModel(SDValue Op, SelectionDAG &DAG) const;
245
SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
246
SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const;
247
248
SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
249
SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
250
SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
251
/// } Custom Lower
252
253
/// Replace the results of node with an illegal result
254
/// type with new values built out of custom code.
255
///
256
void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
257
SelectionDAG &DAG) const override;
258
259
/// Custom Inserter {
260
MachineBasicBlock *
261
EmitInstrWithCustomInserter(MachineInstr &MI,
262
MachineBasicBlock *MBB) const override;
263
MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI,
264
MachineBasicBlock *MBB) const;
265
MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI,
266
MachineBasicBlock *MBB) const;
267
MachineBasicBlock *emitSjLjDispatchBlock(MachineInstr &MI,
268
MachineBasicBlock *BB) const;
269
270
void setupEntryBlockForSjLj(MachineInstr &MI, MachineBasicBlock *MBB,
271
MachineBasicBlock *DispatchBB, int FI,
272
int Offset) const;
273
// Setup basic block address.
274
Register prepareMBB(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
275
MachineBasicBlock *TargetBB, const DebugLoc &DL) const;
276
// Prepare function/variable address.
277
Register prepareSymbol(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
278
StringRef Symbol, const DebugLoc &DL, bool IsLocal,
279
bool IsCall) const;
280
/// } Custom Inserter
281
282
/// VVP Lowering {
283
SDValue lowerToVVP(SDValue Op, SelectionDAG &DAG) const;
284
SDValue lowerVVP_LOAD_STORE(SDValue Op, VECustomDAG &) const;
285
SDValue lowerVVP_GATHER_SCATTER(SDValue Op, VECustomDAG &) const;
286
287
SDValue legalizeInternalVectorOp(SDValue Op, SelectionDAG &DAG) const;
288
SDValue legalizeInternalLoadStoreOp(SDValue Op, VECustomDAG &CDAG) const;
289
SDValue splitVectorOp(SDValue Op, VECustomDAG &CDAG) const;
290
SDValue splitPackedLoadStore(SDValue Op, VECustomDAG &CDAG) const;
291
SDValue legalizePackedAVL(SDValue Op, VECustomDAG &CDAG) const;
292
SDValue splitMaskArithmetic(SDValue Op, SelectionDAG &DAG) const;
293
/// } VVPLowering
294
295
/// Custom DAGCombine {
296
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
297
298
SDValue combineSelect(SDNode *N, DAGCombinerInfo &DCI) const;
299
SDValue combineSelectCC(SDNode *N, DAGCombinerInfo &DCI) const;
300
SDValue combineTRUNCATE(SDNode *N, DAGCombinerInfo &DCI) const;
301
/// } Custom DAGCombine
302
303
SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const;
304
SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF,
305
SelectionDAG &DAG) const;
306
SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const;
307
308
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
309
bool isFPImmLegal(const APFloat &Imm, EVT VT,
310
bool ForCodeSize) const override;
311
/// Returns true if the target allows unaligned memory accesses of the
312
/// specified type.
313
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align A,
314
MachineMemOperand::Flags Flags,
315
unsigned *Fast) const override;
316
317
/// Inline Assembly {
318
319
ConstraintType getConstraintType(StringRef Constraint) const override;
320
std::pair<unsigned, const TargetRegisterClass *>
321
getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
322
StringRef Constraint, MVT VT) const override;
323
324
/// } Inline Assembly
325
326
/// Target Optimization {
327
328
// Return lower limit for number of blocks in a jump table.
329
unsigned getMinimumJumpTableEntries() const override;
330
331
// SX-Aurora VE's s/udiv is 5-9 times slower than multiply.
332
bool isIntDivCheap(EVT, AttributeList) const override { return false; }
333
// VE doesn't have rem.
334
bool hasStandaloneRem(EVT) const override { return false; }
335
// VE LDZ instruction returns 64 if the input is zero.
336
bool isCheapToSpeculateCtlz(Type *) const override { return true; }
337
// VE LDZ instruction is fast.
338
bool isCtlzFast() const override { return true; }
339
// VE has NND instruction.
340
bool hasAndNot(SDValue Y) const override;
341
342
/// } Target Optimization
343
};
344
} // namespace llvm
345
346
#endif // LLVM_LIB_TARGET_VE_VEISELLOWERING_H
347
348