Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
35269 views
1
//=- LoongArchISelLowering.h - LoongArch 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 LoongArch uses to lower LLVM code into
10
// a selection DAG.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H
15
#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H
16
17
#include "LoongArch.h"
18
#include "llvm/CodeGen/CallingConvLower.h"
19
#include "llvm/CodeGen/SelectionDAG.h"
20
#include "llvm/CodeGen/TargetLowering.h"
21
22
namespace llvm {
23
class LoongArchSubtarget;
24
namespace LoongArchISD {
25
enum NodeType : unsigned {
26
FIRST_NUMBER = ISD::BUILTIN_OP_END,
27
28
// TODO: add more LoongArchISDs
29
CALL,
30
CALL_MEDIUM,
31
CALL_LARGE,
32
RET,
33
TAIL,
34
TAIL_MEDIUM,
35
TAIL_LARGE,
36
37
// 32-bit shifts, directly matching the semantics of the named LoongArch
38
// instructions.
39
SLL_W,
40
SRA_W,
41
SRL_W,
42
43
ROTL_W,
44
ROTR_W,
45
46
// unsigned 32-bit integer division
47
DIV_WU,
48
MOD_WU,
49
50
// FPR<->GPR transfer operations
51
MOVGR2FR_W_LA64,
52
MOVFR2GR_S_LA64,
53
MOVFCSR2GR,
54
MOVGR2FCSR,
55
56
FTINT,
57
58
// Bit counting operations
59
CLZ_W,
60
CTZ_W,
61
62
BSTRINS,
63
BSTRPICK,
64
65
// Byte-swapping and bit-reversal
66
REVB_2H,
67
REVB_2W,
68
BITREV_4B,
69
BITREV_W,
70
71
// Intrinsic operations start ============================================
72
BREAK,
73
CACOP_D,
74
CACOP_W,
75
DBAR,
76
IBAR,
77
SYSCALL,
78
79
// CRC check operations
80
CRC_W_B_W,
81
CRC_W_H_W,
82
CRC_W_W_W,
83
CRC_W_D_W,
84
CRCC_W_B_W,
85
CRCC_W_H_W,
86
CRCC_W_W_W,
87
CRCC_W_D_W,
88
89
CSRRD,
90
91
// Write new value to CSR and return old value.
92
// Operand 0: A chain pointer.
93
// Operand 1: The new value to write.
94
// Operand 2: The address of the required CSR.
95
// Result 0: The old value of the CSR.
96
// Result 1: The new chain pointer.
97
CSRWR,
98
99
// Similar to CSRWR but with a write mask.
100
// Operand 0: A chain pointer.
101
// Operand 1: The new value to write.
102
// Operand 2: The write mask.
103
// Operand 3: The address of the required CSR.
104
// Result 0: The old value of the CSR.
105
// Result 1: The new chain pointer.
106
CSRXCHG,
107
108
// IOCSR access operations
109
IOCSRRD_B,
110
IOCSRRD_W,
111
IOCSRRD_H,
112
IOCSRRD_D,
113
IOCSRWR_B,
114
IOCSRWR_H,
115
IOCSRWR_W,
116
IOCSRWR_D,
117
118
// Read CPU configuration information operation
119
CPUCFG,
120
121
// Vector Shuffle
122
VREPLVE,
123
VSHUF,
124
VPICKEV,
125
VPICKOD,
126
VPACKEV,
127
VPACKOD,
128
VILVL,
129
VILVH,
130
VSHUF4I,
131
VREPLVEI,
132
XVPERMI,
133
134
// Extended vector element extraction
135
VPICK_SEXT_ELT,
136
VPICK_ZEXT_ELT,
137
138
// Vector comparisons
139
VALL_ZERO,
140
VANY_ZERO,
141
VALL_NONZERO,
142
VANY_NONZERO,
143
144
// Intrinsic operations end =============================================
145
};
146
} // end namespace LoongArchISD
147
148
class LoongArchTargetLowering : public TargetLowering {
149
const LoongArchSubtarget &Subtarget;
150
151
public:
152
explicit LoongArchTargetLowering(const TargetMachine &TM,
153
const LoongArchSubtarget &STI);
154
155
const LoongArchSubtarget &getSubtarget() const { return Subtarget; }
156
157
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
158
159
// Provide custom lowering hooks for some operations.
160
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
161
void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
162
SelectionDAG &DAG) const override;
163
164
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
165
166
// This method returns the name of a target specific DAG node.
167
const char *getTargetNodeName(unsigned Opcode) const override;
168
169
// Lower incoming arguments, copy physregs into vregs.
170
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
171
bool IsVarArg,
172
const SmallVectorImpl<ISD::InputArg> &Ins,
173
const SDLoc &DL, SelectionDAG &DAG,
174
SmallVectorImpl<SDValue> &InVals) const override;
175
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
176
bool IsVarArg,
177
const SmallVectorImpl<ISD::OutputArg> &Outs,
178
LLVMContext &Context) const override;
179
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
180
const SmallVectorImpl<ISD::OutputArg> &Outs,
181
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
182
SelectionDAG &DAG) const override;
183
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
184
SmallVectorImpl<SDValue> &InVals) const override;
185
bool isCheapToSpeculateCttz(Type *Ty) const override;
186
bool isCheapToSpeculateCtlz(Type *Ty) const override;
187
bool hasAndNot(SDValue Y) const override;
188
TargetLowering::AtomicExpansionKind
189
shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override;
190
191
Value *emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI,
192
Value *AlignedAddr, Value *Incr,
193
Value *Mask, Value *ShiftAmt,
194
AtomicOrdering Ord) const override;
195
196
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
197
EVT VT) const override;
198
TargetLowering::AtomicExpansionKind
199
shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *CI) const override;
200
Value *emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder,
201
AtomicCmpXchgInst *CI,
202
Value *AlignedAddr, Value *CmpVal,
203
Value *NewVal, Value *Mask,
204
AtomicOrdering Ord) const override;
205
206
bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I,
207
MachineFunction &MF,
208
unsigned Intrinsic) const override;
209
210
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
211
EVT VT) const override;
212
213
Register
214
getExceptionPointerRegister(const Constant *PersonalityFn) const override;
215
216
Register
217
getExceptionSelectorRegister(const Constant *PersonalityFn) const override;
218
219
ISD::NodeType getExtendForAtomicOps() const override {
220
return ISD::SIGN_EXTEND;
221
}
222
223
ISD::NodeType getExtendForAtomicCmpSwapArg() const override;
224
225
Register getRegisterByName(const char *RegName, LLT VT,
226
const MachineFunction &MF) const override;
227
bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
228
229
bool decomposeMulByConstant(LLVMContext &Context, EVT VT,
230
SDValue C) const override;
231
232
bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override;
233
234
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty,
235
unsigned AS,
236
Instruction *I = nullptr) const override;
237
238
bool isLegalICmpImmediate(int64_t Imm) const override;
239
bool isLegalAddImmediate(int64_t Imm) const override;
240
bool isZExtFree(SDValue Val, EVT VT2) const override;
241
bool isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const override;
242
bool signExtendConstant(const ConstantInt *CI) const override;
243
244
bool hasAndNotCompare(SDValue Y) const override;
245
246
bool convertSelectOfConstantsToMath(EVT VT) const override { return true; }
247
248
bool allowsMisalignedMemoryAccesses(
249
EVT VT, unsigned AddrSpace = 0, Align Alignment = Align(1),
250
MachineMemOperand::Flags Flags = MachineMemOperand::MONone,
251
unsigned *Fast = nullptr) const override;
252
253
bool isShuffleMaskLegal(ArrayRef<int> Mask, EVT VT) const override {
254
return false;
255
}
256
bool shouldConsiderGEPOffsetSplit() const override { return true; }
257
bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const override;
258
bool shouldExtendTypeInLibCall(EVT Type) const override;
259
260
private:
261
/// Target-specific function used to lower LoongArch calling conventions.
262
typedef bool LoongArchCCAssignFn(const DataLayout &DL, LoongArchABI::ABI ABI,
263
unsigned ValNo, MVT ValVT,
264
CCValAssign::LocInfo LocInfo,
265
ISD::ArgFlagsTy ArgFlags, CCState &State,
266
bool IsFixed, bool IsReg, Type *OrigTy);
267
268
void analyzeInputArgs(MachineFunction &MF, CCState &CCInfo,
269
const SmallVectorImpl<ISD::InputArg> &Ins, bool IsRet,
270
LoongArchCCAssignFn Fn) const;
271
void analyzeOutputArgs(MachineFunction &MF, CCState &CCInfo,
272
const SmallVectorImpl<ISD::OutputArg> &Outs,
273
bool IsRet, CallLoweringInfo *CLI,
274
LoongArchCCAssignFn Fn) const;
275
276
template <class NodeTy>
277
SDValue getAddr(NodeTy *N, SelectionDAG &DAG, CodeModel::Model M,
278
bool IsLocal = true) const;
279
SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,
280
unsigned Opc, bool UseGOT, bool Large = false) const;
281
SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,
282
unsigned Opc, bool Large = false) const;
283
SDValue getTLSDescAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,
284
unsigned Opc, bool Large = false) const;
285
SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
286
SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
287
SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
288
SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
289
SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;
290
SDValue lowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const;
291
292
MachineBasicBlock *
293
EmitInstrWithCustomInserter(MachineInstr &MI,
294
MachineBasicBlock *BB) const override;
295
SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const;
296
SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
297
SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const;
298
SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const;
299
SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const;
300
SDValue lowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
301
SDValue lowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
302
SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
303
SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
304
SDValue lowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const;
305
SDValue lowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;
306
SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
307
SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
308
SDValue lowerWRITE_REGISTER(SDValue Op, SelectionDAG &DAG) const;
309
SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
310
SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
311
SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
312
SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
313
314
bool isFPImmLegal(const APFloat &Imm, EVT VT,
315
bool ForCodeSize) const override;
316
317
bool shouldInsertFencesForAtomic(const Instruction *I) const override;
318
319
ConstraintType getConstraintType(StringRef Constraint) const override;
320
321
InlineAsm::ConstraintCode
322
getInlineAsmMemConstraint(StringRef ConstraintCode) const override;
323
324
std::pair<unsigned, const TargetRegisterClass *>
325
getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
326
StringRef Constraint, MVT VT) const override;
327
328
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint,
329
std::vector<SDValue> &Ops,
330
SelectionDAG &DAG) const override;
331
332
bool isEligibleForTailCallOptimization(
333
CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF,
334
const SmallVectorImpl<CCValAssign> &ArgLocs) const;
335
};
336
337
} // end namespace llvm
338
339
#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H
340
341