1 //===-- RISCVInstrInfo.h - RISC-V Instruction Information -------*- 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 contains the RISC-V implementation of the TargetInstrInfo class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H 14 #define LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H 15 16 #include "RISCVRegisterInfo.h" 17 #include "llvm/CodeGen/TargetInstrInfo.h" 18 #include "llvm/IR/DiagnosticInfo.h" 19 20 #define GET_INSTRINFO_HEADER 21 #define GET_INSTRINFO_OPERAND_ENUM 22 #include "RISCVGenInstrInfo.inc" 23 24 namespace llvm { 25 26 class RISCVSubtarget; 27 28 static const MachineMemOperand::Flags MONontemporalBit0 = 29 MachineMemOperand::MOTargetFlag1; 30 static const MachineMemOperand::Flags MONontemporalBit1 = 31 MachineMemOperand::MOTargetFlag2; 32 33 namespace RISCVCC { 34 35 enum CondCode { 36 COND_EQ, 37 COND_NE, 38 COND_LT, 39 COND_GE, 40 COND_LTU, 41 COND_GEU, 42 COND_INVALID 43 }; 44 45 CondCode getOppositeBranchCondition(CondCode); 46 unsigned getBrCond(CondCode CC); 47 48 } // end of namespace RISCVCC 49 50 class RISCVInstrInfo : public RISCVGenInstrInfo { 51 52 public: 53 explicit RISCVInstrInfo(RISCVSubtarget &STI); 54 55 MCInst getNop() const override; 56 const MCInstrDesc &getBrCond(RISCVCC::CondCode CC) const; 57 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; 66 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; 74 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; 81 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; 87 88 using TargetInstrInfo::foldMemoryOperandImpl; 89 MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, 90 ArrayRef<unsigned> Ops, 91 MachineBasicBlock::iterator InsertPt, 92 int FrameIndex, 93 LiveIntervals *LIS = nullptr, 94 VirtRegMap *VRM = nullptr) const override; 95 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; 101 102 unsigned getInstSizeInBytes(const MachineInstr &MI) const override; 103 104 bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 105 MachineBasicBlock *&FBB, 106 SmallVectorImpl<MachineOperand> &Cond, 107 bool AllowModify) const override; 108 109 unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 110 MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, 111 const DebugLoc &dl, 112 int *BytesAdded = nullptr) const override; 113 114 void insertIndirectBranch(MachineBasicBlock &MBB, 115 MachineBasicBlock &NewDestBB, 116 MachineBasicBlock &RestoreBB, const DebugLoc &DL, 117 int64_t BrOffset, RegScavenger *RS) const override; 118 119 unsigned removeBranch(MachineBasicBlock &MBB, 120 int *BytesRemoved = nullptr) const override; 121 122 bool 123 reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; 124 125 bool optimizeCondBranch(MachineInstr &MI) const override; 126 127 MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override; 128 129 bool isBranchOffsetInRange(unsigned BranchOpc, 130 int64_t BrOffset) const override; 131 132 bool analyzeSelect(const MachineInstr &MI, 133 SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp, 134 unsigned &FalseOp, bool &Optimizable) const override; 135 136 MachineInstr *optimizeSelect(MachineInstr &MI, 137 SmallPtrSetImpl<MachineInstr *> &SeenMIs, 138 bool) const override; 139 140 bool isAsCheapAsAMove(const MachineInstr &MI) const override; 141 142 std::optional<DestSourcePair> 143 isCopyInstrImpl(const MachineInstr &MI) const override; 144 145 bool verifyInstruction(const MachineInstr &MI, 146 StringRef &ErrInfo) const override; 147 148 bool canFoldIntoAddrMode(const MachineInstr &MemI, Register Reg, 149 const MachineInstr &AddrI, 150 ExtAddrMode &AM) const override; 151 152 MachineInstr *emitLdStWithAddr(MachineInstr &MemI, 153 const ExtAddrMode &AM) const override; 154 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; 159 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; 166 167 bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, 168 const MachineOperand *&BaseOp, 169 int64_t &Offset, unsigned &Width, 170 const TargetRegisterInfo *TRI) const; 171 172 bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, 173 const MachineInstr &MIb) const override; 174 175 176 std::pair<unsigned, unsigned> 177 decomposeMachineOperandsTargetFlags(unsigned TF) const override; 178 179 ArrayRef<std::pair<unsigned, const char *>> 180 getSerializableDirectMachineOperandTargetFlags() const override; 181 182 // Return true if the function can safely be outlined from. 183 bool isFunctionSafeToOutlineFrom(MachineFunction &MF, 184 bool OutlineFromLinkOnceODRs) const override; 185 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; 190 191 bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override; 192 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; 196 197 // Return if/how a given MachineInstr should be outlined. 198 virtual outliner::InstrType 199 getOutliningTypeImpl(MachineBasicBlock::iterator &MBBI, 200 unsigned Flags) const override; 201 202 // Insert a custom frame for outlined functions. 203 void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF, 204 const outliner::OutlinedFunction &OF) const override; 205 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; 211 212 std::optional<RegImmPair> isAddImmediate(const MachineInstr &MI, 213 Register Reg) const override; 214 215 bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, 216 unsigned &SrcOpIdx2) const override; 217 MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI, 218 unsigned OpIdx1, 219 unsigned OpIdx2) const override; 220 221 MachineInstr *convertToThreeAddress(MachineInstr &MI, LiveVariables *LV, 222 LiveIntervals *LIS) const override; 223 224 // MIR printer helper function to annotate Operands with a comment. 225 std::string 226 createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, 227 unsigned OpIdx, 228 const TargetRegisterInfo *TRI) const override; 229 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; 234 235 bool useMachineCombiner() const override { return true; } 236 237 MachineTraceStrategy getMachineCombinerTraceStrategy() const override; 238 239 bool 240 getMachineCombinerPatterns(MachineInstr &Root, 241 SmallVectorImpl<MachineCombinerPattern> &Patterns, 242 bool DoRegPressureReduce) const override; 243 244 void 245 finalizeInsInstrs(MachineInstr &Root, MachineCombinerPattern &P, 246 SmallVectorImpl<MachineInstr *> &InsInstrs) const override; 247 248 void genAlternativeCodeSequence( 249 MachineInstr &Root, MachineCombinerPattern Pattern, 250 SmallVectorImpl<MachineInstr *> &InsInstrs, 251 SmallVectorImpl<MachineInstr *> &DelInstrs, 252 DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const override; 253 254 bool hasReassociableSibling(const MachineInstr &Inst, 255 bool &Commuted) const override; 256 257 bool isAssociativeAndCommutative(const MachineInstr &Inst, 258 bool Invert) const override; 259 260 std::optional<unsigned> getInverseOpcode(unsigned Opcode) const override; 261 262 ArrayRef<std::pair<MachineMemOperand::Flags, const char *>> 263 getSerializableMachineMemOperandTargetFlags() const override; 264 265 protected: 266 const RISCVSubtarget &STI; 267 268 private: 269 unsigned getInstBundleLength(const MachineInstr &MI) const; 270 }; 271 272 namespace RISCV { 273 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); 278 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); 282 283 std::optional<std::pair<unsigned, unsigned>> 284 isRVVSpillForZvlsseg(unsigned Opcode); 285 286 bool isFaultFirstLoad(const MachineInstr &MI); 287 288 // Implemented in RISCVGenInstrInfo.inc 289 int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex); 290 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); 294 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 297 // returns null. 298 std::optional<unsigned> getVectorLowDemandedScalarBits(uint16_t Opcode, 299 unsigned Log2SEW); 300 301 // Returns the MC opcode of RVV pseudo instruction. 302 unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode); 303 304 // Special immediate for AVL operand of V pseudo instructions to indicate VLMax. 305 static constexpr int64_t VLMaxSentinel = -1LL; 306 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; 318 } // namespace RISCV 319 320 namespace RISCVVPseudosTable { 321 322 struct PseudoInfo { 323 uint16_t Pseudo; 324 uint16_t BaseInstr; 325 }; 326 327 #define GET_RISCVVPseudosTable_DECL 328 #include "RISCVGenSearchableTables.inc" 329 330 } // end namespace RISCVVPseudosTable 331 332 } // end namespace llvm 333 #endif 334