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

source code of llvm/lib/Target/LoongArch/LoongArchISelLowering.h