1 //===-- RISCVInstrInfo.h - RISC-V Instruction Information -------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains the RISC-V implementation of the TargetInstrInfo class.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H
14 #define LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H
16 #include "RISCVRegisterInfo.h"
17 #include "llvm/CodeGen/TargetInstrInfo.h"
18 #include "llvm/IR/DiagnosticInfo.h"
20 #define GET_INSTRINFO_HEADER
21 #define GET_INSTRINFO_OPERAND_ENUM
22 #include "RISCVGenInstrInfo.inc"
28 static const MachineMemOperand::Flags MONontemporalBit0
=
29 MachineMemOperand::MOTargetFlag1
;
30 static const MachineMemOperand::Flags MONontemporalBit1
=
31 MachineMemOperand::MOTargetFlag2
;
45 CondCode
getOppositeBranchCondition(CondCode
);
46 unsigned getBrCond(CondCode CC
);
48 } // end of namespace RISCVCC
50 class RISCVInstrInfo
: public RISCVGenInstrInfo
{
53 explicit RISCVInstrInfo(RISCVSubtarget
&STI
);
55 MCInst
getNop() const override
;
56 const MCInstrDesc
&getBrCond(RISCVCC::CondCode CC
) const;
58 unsigned isLoadFromStackSlot(const MachineInstr
&MI
,
59 int &FrameIndex
) const override
;
60 unsigned isLoadFromStackSlot(const MachineInstr
&MI
, int &FrameIndex
,
61 unsigned &MemBytes
) const override
;
62 unsigned isStoreToStackSlot(const MachineInstr
&MI
,
63 int &FrameIndex
) const override
;
64 unsigned isStoreToStackSlot(const MachineInstr
&MI
, int &FrameIndex
,
65 unsigned &MemBytes
) const override
;
67 void copyPhysRegVector(MachineBasicBlock
&MBB
,
68 MachineBasicBlock::iterator MBBI
, const DebugLoc
&DL
,
69 MCRegister DstReg
, MCRegister SrcReg
, bool KillSrc
,
70 unsigned Opc
, unsigned NF
= 1) const;
71 void copyPhysReg(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
,
72 const DebugLoc
&DL
, MCRegister DstReg
, MCRegister SrcReg
,
73 bool KillSrc
) const override
;
75 void storeRegToStackSlot(MachineBasicBlock
&MBB
,
76 MachineBasicBlock::iterator MBBI
, Register SrcReg
,
77 bool IsKill
, int FrameIndex
,
78 const TargetRegisterClass
*RC
,
79 const TargetRegisterInfo
*TRI
,
80 Register VReg
) const override
;
82 void loadRegFromStackSlot(MachineBasicBlock
&MBB
,
83 MachineBasicBlock::iterator MBBI
, Register DstReg
,
84 int FrameIndex
, const TargetRegisterClass
*RC
,
85 const TargetRegisterInfo
*TRI
,
86 Register VReg
) const override
;
88 using TargetInstrInfo::foldMemoryOperandImpl
;
89 MachineInstr
*foldMemoryOperandImpl(MachineFunction
&MF
, MachineInstr
&MI
,
90 ArrayRef
<unsigned> Ops
,
91 MachineBasicBlock::iterator InsertPt
,
93 LiveIntervals
*LIS
= nullptr,
94 VirtRegMap
*VRM
= nullptr) const override
;
96 // Materializes the given integer Val into DstReg.
97 void movImm(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
,
98 const DebugLoc
&DL
, Register DstReg
, uint64_t Val
,
99 MachineInstr::MIFlag Flag
= MachineInstr::NoFlags
,
100 bool DstRenamable
= false, bool DstIsDead
= false) const;
102 unsigned getInstSizeInBytes(const MachineInstr
&MI
) const override
;
104 bool analyzeBranch(MachineBasicBlock
&MBB
, MachineBasicBlock
*&TBB
,
105 MachineBasicBlock
*&FBB
,
106 SmallVectorImpl
<MachineOperand
> &Cond
,
107 bool AllowModify
) const override
;
109 unsigned insertBranch(MachineBasicBlock
&MBB
, MachineBasicBlock
*TBB
,
110 MachineBasicBlock
*FBB
, ArrayRef
<MachineOperand
> Cond
,
112 int *BytesAdded
= nullptr) const override
;
114 void insertIndirectBranch(MachineBasicBlock
&MBB
,
115 MachineBasicBlock
&NewDestBB
,
116 MachineBasicBlock
&RestoreBB
, const DebugLoc
&DL
,
117 int64_t BrOffset
, RegScavenger
*RS
) const override
;
119 unsigned removeBranch(MachineBasicBlock
&MBB
,
120 int *BytesRemoved
= nullptr) const override
;
123 reverseBranchCondition(SmallVectorImpl
<MachineOperand
> &Cond
) const override
;
125 bool optimizeCondBranch(MachineInstr
&MI
) const override
;
127 MachineBasicBlock
*getBranchDestBlock(const MachineInstr
&MI
) const override
;
129 bool isBranchOffsetInRange(unsigned BranchOpc
,
130 int64_t BrOffset
) const override
;
132 bool analyzeSelect(const MachineInstr
&MI
,
133 SmallVectorImpl
<MachineOperand
> &Cond
, unsigned &TrueOp
,
134 unsigned &FalseOp
, bool &Optimizable
) const override
;
136 MachineInstr
*optimizeSelect(MachineInstr
&MI
,
137 SmallPtrSetImpl
<MachineInstr
*> &SeenMIs
,
138 bool) const override
;
140 bool isAsCheapAsAMove(const MachineInstr
&MI
) const override
;
142 std::optional
<DestSourcePair
>
143 isCopyInstrImpl(const MachineInstr
&MI
) const override
;
145 bool verifyInstruction(const MachineInstr
&MI
,
146 StringRef
&ErrInfo
) const override
;
148 bool canFoldIntoAddrMode(const MachineInstr
&MemI
, Register Reg
,
149 const MachineInstr
&AddrI
,
150 ExtAddrMode
&AM
) const override
;
152 MachineInstr
*emitLdStWithAddr(MachineInstr
&MemI
,
153 const ExtAddrMode
&AM
) const override
;
155 bool getMemOperandsWithOffsetWidth(
156 const MachineInstr
&MI
, SmallVectorImpl
<const MachineOperand
*> &BaseOps
,
157 int64_t &Offset
, bool &OffsetIsScalable
, unsigned &Width
,
158 const TargetRegisterInfo
*TRI
) const override
;
160 bool shouldClusterMemOps(ArrayRef
<const MachineOperand
*> BaseOps1
,
161 int64_t Offset1
, bool OffsetIsScalable1
,
162 ArrayRef
<const MachineOperand
*> BaseOps2
,
163 int64_t Offset2
, bool OffsetIsScalable2
,
164 unsigned ClusterSize
,
165 unsigned NumBytes
) const override
;
167 bool getMemOperandWithOffsetWidth(const MachineInstr
&LdSt
,
168 const MachineOperand
*&BaseOp
,
169 int64_t &Offset
, unsigned &Width
,
170 const TargetRegisterInfo
*TRI
) const;
172 bool areMemAccessesTriviallyDisjoint(const MachineInstr
&MIa
,
173 const MachineInstr
&MIb
) const override
;
176 std::pair
<unsigned, unsigned>
177 decomposeMachineOperandsTargetFlags(unsigned TF
) const override
;
179 ArrayRef
<std::pair
<unsigned, const char *>>
180 getSerializableDirectMachineOperandTargetFlags() const override
;
182 // Return true if the function can safely be outlined from.
183 bool isFunctionSafeToOutlineFrom(MachineFunction
&MF
,
184 bool OutlineFromLinkOnceODRs
) const override
;
186 // Return true if MBB is safe to outline from, and return any target-specific
187 // information in Flags.
188 bool isMBBSafeToOutlineFrom(MachineBasicBlock
&MBB
,
189 unsigned &Flags
) const override
;
191 bool shouldOutlineFromFunctionByDefault(MachineFunction
&MF
) const override
;
193 // Calculate target-specific information for a set of outlining candidates.
194 std::optional
<outliner::OutlinedFunction
> getOutliningCandidateInfo(
195 std::vector
<outliner::Candidate
> &RepeatedSequenceLocs
) const override
;
197 // Return if/how a given MachineInstr should be outlined.
198 virtual outliner::InstrType
199 getOutliningTypeImpl(MachineBasicBlock::iterator
&MBBI
,
200 unsigned Flags
) const override
;
202 // Insert a custom frame for outlined functions.
203 void buildOutlinedFrame(MachineBasicBlock
&MBB
, MachineFunction
&MF
,
204 const outliner::OutlinedFunction
&OF
) const override
;
206 // Insert a call to an outlined function into a given basic block.
207 MachineBasicBlock::iterator
208 insertOutlinedCall(Module
&M
, MachineBasicBlock
&MBB
,
209 MachineBasicBlock::iterator
&It
, MachineFunction
&MF
,
210 outliner::Candidate
&C
) const override
;
212 std::optional
<RegImmPair
> isAddImmediate(const MachineInstr
&MI
,
213 Register Reg
) const override
;
215 bool findCommutedOpIndices(const MachineInstr
&MI
, unsigned &SrcOpIdx1
,
216 unsigned &SrcOpIdx2
) const override
;
217 MachineInstr
*commuteInstructionImpl(MachineInstr
&MI
, bool NewMI
,
219 unsigned OpIdx2
) const override
;
221 MachineInstr
*convertToThreeAddress(MachineInstr
&MI
, LiveVariables
*LV
,
222 LiveIntervals
*LIS
) const override
;
224 // MIR printer helper function to annotate Operands with a comment.
226 createMIROperandComment(const MachineInstr
&MI
, const MachineOperand
&Op
,
228 const TargetRegisterInfo
*TRI
) const override
;
230 void getVLENFactoredAmount(
231 MachineFunction
&MF
, MachineBasicBlock
&MBB
,
232 MachineBasicBlock::iterator II
, const DebugLoc
&DL
, Register DestReg
,
233 int64_t Amount
, MachineInstr::MIFlag Flag
= MachineInstr::NoFlags
) const;
235 bool useMachineCombiner() const override
{ return true; }
237 MachineTraceStrategy
getMachineCombinerTraceStrategy() const override
;
240 getMachineCombinerPatterns(MachineInstr
&Root
,
241 SmallVectorImpl
<MachineCombinerPattern
> &Patterns
,
242 bool DoRegPressureReduce
) const override
;
245 finalizeInsInstrs(MachineInstr
&Root
, MachineCombinerPattern
&P
,
246 SmallVectorImpl
<MachineInstr
*> &InsInstrs
) const override
;
248 void genAlternativeCodeSequence(
249 MachineInstr
&Root
, MachineCombinerPattern Pattern
,
250 SmallVectorImpl
<MachineInstr
*> &InsInstrs
,
251 SmallVectorImpl
<MachineInstr
*> &DelInstrs
,
252 DenseMap
<unsigned, unsigned> &InstrIdxForVirtReg
) const override
;
254 bool hasReassociableSibling(const MachineInstr
&Inst
,
255 bool &Commuted
) const override
;
257 bool isAssociativeAndCommutative(const MachineInstr
&Inst
,
258 bool Invert
) const override
;
260 std::optional
<unsigned> getInverseOpcode(unsigned Opcode
) const override
;
262 ArrayRef
<std::pair
<MachineMemOperand::Flags
, const char *>>
263 getSerializableMachineMemOperandTargetFlags() const override
;
266 const RISCVSubtarget
&STI
;
269 unsigned getInstBundleLength(const MachineInstr
&MI
) const;
274 // Returns true if this is the sext.w pattern, addiw rd, rs1, 0.
275 bool isSEXT_W(const MachineInstr
&MI
);
276 bool isZEXT_W(const MachineInstr
&MI
);
277 bool isZEXT_B(const MachineInstr
&MI
);
279 // Returns true if the given MI is an RVV instruction opcode for which we may
280 // expect to see a FrameIndex operand.
281 bool isRVVSpill(const MachineInstr
&MI
);
283 std::optional
<std::pair
<unsigned, unsigned>>
284 isRVVSpillForZvlsseg(unsigned Opcode
);
286 bool isFaultFirstLoad(const MachineInstr
&MI
);
288 // Implemented in RISCVGenInstrInfo.inc
289 int16_t getNamedOperandIdx(uint16_t Opcode
, uint16_t NamedIndex
);
291 // Return true if both input instructions have equal rounding mode. If at least
292 // one of the instructions does not have rounding mode, false will be returned.
293 bool hasEqualFRM(const MachineInstr
&MI1
, const MachineInstr
&MI2
);
295 // If \p Opcode is a .vx vector instruction, returns the lower number of bits
296 // that are used from the scalar .x operand for a given \p Log2SEW. Otherwise
298 std::optional
<unsigned> getVectorLowDemandedScalarBits(uint16_t Opcode
,
301 // Returns the MC opcode of RVV pseudo instruction.
302 unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode
);
304 // Special immediate for AVL operand of V pseudo instructions to indicate VLMax.
305 static constexpr int64_t VLMaxSentinel
= -1LL;
307 // Mask assignments for floating-point
308 static constexpr unsigned FPMASK_Negative_Infinity
= 0x001;
309 static constexpr unsigned FPMASK_Negative_Normal
= 0x002;
310 static constexpr unsigned FPMASK_Negative_Subnormal
= 0x004;
311 static constexpr unsigned FPMASK_Negative_Zero
= 0x008;
312 static constexpr unsigned FPMASK_Positive_Zero
= 0x010;
313 static constexpr unsigned FPMASK_Positive_Subnormal
= 0x020;
314 static constexpr unsigned FPMASK_Positive_Normal
= 0x040;
315 static constexpr unsigned FPMASK_Positive_Infinity
= 0x080;
316 static constexpr unsigned FPMASK_Signaling_NaN
= 0x100;
317 static constexpr unsigned FPMASK_Quiet_NaN
= 0x200;
320 namespace RISCVVPseudosTable
{
327 #define GET_RISCVVPseudosTable_DECL
328 #include "RISCVGenSearchableTables.inc"
330 } // end namespace RISCVVPseudosTable
332 } // end namespace llvm