106c3fb27SDimitry Andric //===-- RISCVInstrInfo.h - RISC-V Instruction Information -------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 906c3fb27SDimitry Andric // This file contains the RISC-V implementation of the TargetInstrInfo class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H 140b57cec5SDimitry Andric #define LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H 150b57cec5SDimitry Andric 16*0fca6ea1SDimitry Andric #include "RISCV.h" 170b57cec5SDimitry Andric #include "RISCVRegisterInfo.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 19fe6060f1SDimitry Andric #include "llvm/IR/DiagnosticInfo.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric #define GET_INSTRINFO_HEADER 220eae32dcSDimitry Andric #define GET_INSTRINFO_OPERAND_ENUM 230b57cec5SDimitry Andric #include "RISCVGenInstrInfo.inc" 24*0fca6ea1SDimitry Andric #include "RISCVGenRegisterInfo.inc" 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric namespace llvm { 270b57cec5SDimitry Andric 288bcb0991SDimitry Andric class RISCVSubtarget; 298bcb0991SDimitry Andric 3006c3fb27SDimitry Andric static const MachineMemOperand::Flags MONontemporalBit0 = 3106c3fb27SDimitry Andric MachineMemOperand::MOTargetFlag1; 3206c3fb27SDimitry Andric static const MachineMemOperand::Flags MONontemporalBit1 = 3306c3fb27SDimitry Andric MachineMemOperand::MOTargetFlag2; 3406c3fb27SDimitry Andric 35349cc55cSDimitry Andric namespace RISCVCC { 36349cc55cSDimitry Andric 37349cc55cSDimitry Andric enum CondCode { 38349cc55cSDimitry Andric COND_EQ, 39349cc55cSDimitry Andric COND_NE, 40349cc55cSDimitry Andric COND_LT, 41349cc55cSDimitry Andric COND_GE, 42349cc55cSDimitry Andric COND_LTU, 43349cc55cSDimitry Andric COND_GEU, 44349cc55cSDimitry Andric COND_INVALID 45349cc55cSDimitry Andric }; 46349cc55cSDimitry Andric 47349cc55cSDimitry Andric CondCode getOppositeBranchCondition(CondCode); 48*0fca6ea1SDimitry Andric unsigned getBrCond(CondCode CC, bool Imm = false); 49349cc55cSDimitry Andric 50349cc55cSDimitry Andric } // end of namespace RISCVCC 51349cc55cSDimitry Andric 52*0fca6ea1SDimitry Andric // RISCV MachineCombiner patterns 53*0fca6ea1SDimitry Andric enum RISCVMachineCombinerPattern : unsigned { 54*0fca6ea1SDimitry Andric FMADD_AX = MachineCombinerPattern::TARGET_PATTERN_START, 55*0fca6ea1SDimitry Andric FMADD_XA, 56*0fca6ea1SDimitry Andric FMSUB, 57*0fca6ea1SDimitry Andric FNMSUB, 58*0fca6ea1SDimitry Andric SHXADD_ADD_SLLI_OP1, 59*0fca6ea1SDimitry Andric SHXADD_ADD_SLLI_OP2, 60*0fca6ea1SDimitry Andric }; 61*0fca6ea1SDimitry Andric 620b57cec5SDimitry Andric class RISCVInstrInfo : public RISCVGenInstrInfo { 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric public: 658bcb0991SDimitry Andric explicit RISCVInstrInfo(RISCVSubtarget &STI); 660b57cec5SDimitry Andric 67fe6060f1SDimitry Andric MCInst getNop() const override; 68*0fca6ea1SDimitry Andric const MCInstrDesc &getBrCond(RISCVCC::CondCode CC, bool Imm = false) const; 69fe6060f1SDimitry Andric 70*0fca6ea1SDimitry Andric Register isLoadFromStackSlot(const MachineInstr &MI, 710b57cec5SDimitry Andric int &FrameIndex) const override; 72*0fca6ea1SDimitry Andric Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex, 7306c3fb27SDimitry Andric unsigned &MemBytes) const override; 74*0fca6ea1SDimitry Andric Register isStoreToStackSlot(const MachineInstr &MI, 750b57cec5SDimitry Andric int &FrameIndex) const override; 76*0fca6ea1SDimitry Andric Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex, 7706c3fb27SDimitry Andric unsigned &MemBytes) const override; 780b57cec5SDimitry Andric 79*0fca6ea1SDimitry Andric bool isReallyTriviallyReMaterializable(const MachineInstr &MI) const override; 80*0fca6ea1SDimitry Andric 815f757f3fSDimitry Andric void copyPhysRegVector(MachineBasicBlock &MBB, 825f757f3fSDimitry Andric MachineBasicBlock::iterator MBBI, const DebugLoc &DL, 835f757f3fSDimitry Andric MCRegister DstReg, MCRegister SrcReg, bool KillSrc, 84*0fca6ea1SDimitry Andric const TargetRegisterClass *RegClass) const; 850b57cec5SDimitry Andric void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 86480093f4SDimitry Andric const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, 870b57cec5SDimitry Andric bool KillSrc) const override; 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric void storeRegToStackSlot(MachineBasicBlock &MBB, 905ffd83dbSDimitry Andric MachineBasicBlock::iterator MBBI, Register SrcReg, 910b57cec5SDimitry Andric bool IsKill, int FrameIndex, 920b57cec5SDimitry Andric const TargetRegisterClass *RC, 93bdd1243dSDimitry Andric const TargetRegisterInfo *TRI, 94bdd1243dSDimitry Andric Register VReg) const override; 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric void loadRegFromStackSlot(MachineBasicBlock &MBB, 975ffd83dbSDimitry Andric MachineBasicBlock::iterator MBBI, Register DstReg, 980b57cec5SDimitry Andric int FrameIndex, const TargetRegisterClass *RC, 99bdd1243dSDimitry Andric const TargetRegisterInfo *TRI, 100bdd1243dSDimitry Andric Register VReg) const override; 1010b57cec5SDimitry Andric 102fcaf7f86SDimitry Andric using TargetInstrInfo::foldMemoryOperandImpl; 103fcaf7f86SDimitry Andric MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, 104fcaf7f86SDimitry Andric ArrayRef<unsigned> Ops, 105fcaf7f86SDimitry Andric MachineBasicBlock::iterator InsertPt, 106fcaf7f86SDimitry Andric int FrameIndex, 107fcaf7f86SDimitry Andric LiveIntervals *LIS = nullptr, 108fcaf7f86SDimitry Andric VirtRegMap *VRM = nullptr) const override; 109fcaf7f86SDimitry Andric 1108bcb0991SDimitry Andric // Materializes the given integer Val into DstReg. 1118bcb0991SDimitry Andric void movImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 1128bcb0991SDimitry Andric const DebugLoc &DL, Register DstReg, uint64_t Val, 1135f757f3fSDimitry Andric MachineInstr::MIFlag Flag = MachineInstr::NoFlags, 1145f757f3fSDimitry Andric bool DstRenamable = false, bool DstIsDead = false) const; 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric unsigned getInstSizeInBytes(const MachineInstr &MI) const override; 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 1190b57cec5SDimitry Andric MachineBasicBlock *&FBB, 1200b57cec5SDimitry Andric SmallVectorImpl<MachineOperand> &Cond, 1210b57cec5SDimitry Andric bool AllowModify) const override; 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 1240b57cec5SDimitry Andric MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, 1250b57cec5SDimitry Andric const DebugLoc &dl, 1260b57cec5SDimitry Andric int *BytesAdded = nullptr) const override; 1270b57cec5SDimitry Andric 128349cc55cSDimitry Andric void insertIndirectBranch(MachineBasicBlock &MBB, 1290b57cec5SDimitry Andric MachineBasicBlock &NewDestBB, 130349cc55cSDimitry Andric MachineBasicBlock &RestoreBB, const DebugLoc &DL, 131349cc55cSDimitry Andric int64_t BrOffset, RegScavenger *RS) const override; 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric unsigned removeBranch(MachineBasicBlock &MBB, 1340b57cec5SDimitry Andric int *BytesRemoved = nullptr) const override; 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric bool 1370b57cec5SDimitry Andric reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; 1380b57cec5SDimitry Andric 1395f757f3fSDimitry Andric bool optimizeCondBranch(MachineInstr &MI) const override; 1405f757f3fSDimitry Andric 1410b57cec5SDimitry Andric MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override; 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric bool isBranchOffsetInRange(unsigned BranchOpc, 1440b57cec5SDimitry Andric int64_t BrOffset) const override; 1450b57cec5SDimitry Andric 146bdd1243dSDimitry Andric bool analyzeSelect(const MachineInstr &MI, 147bdd1243dSDimitry Andric SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp, 148bdd1243dSDimitry Andric unsigned &FalseOp, bool &Optimizable) const override; 149bdd1243dSDimitry Andric 150bdd1243dSDimitry Andric MachineInstr *optimizeSelect(MachineInstr &MI, 151bdd1243dSDimitry Andric SmallPtrSetImpl<MachineInstr *> &SeenMIs, 152bdd1243dSDimitry Andric bool) const override; 153bdd1243dSDimitry Andric 1540b57cec5SDimitry Andric bool isAsCheapAsAMove(const MachineInstr &MI) const override; 1558bcb0991SDimitry Andric 156bdd1243dSDimitry Andric std::optional<DestSourcePair> 157e8d8bef9SDimitry Andric isCopyInstrImpl(const MachineInstr &MI) const override; 158e8d8bef9SDimitry Andric 1598bcb0991SDimitry Andric bool verifyInstruction(const MachineInstr &MI, 1608bcb0991SDimitry Andric StringRef &ErrInfo) const override; 1618bcb0991SDimitry Andric 1625f757f3fSDimitry Andric bool canFoldIntoAddrMode(const MachineInstr &MemI, Register Reg, 1635f757f3fSDimitry Andric const MachineInstr &AddrI, 1645f757f3fSDimitry Andric ExtAddrMode &AM) const override; 1655f757f3fSDimitry Andric 1665f757f3fSDimitry Andric MachineInstr *emitLdStWithAddr(MachineInstr &MemI, 1675f757f3fSDimitry Andric const ExtAddrMode &AM) const override; 1685f757f3fSDimitry Andric 1695f757f3fSDimitry Andric bool getMemOperandsWithOffsetWidth( 1705f757f3fSDimitry Andric const MachineInstr &MI, SmallVectorImpl<const MachineOperand *> &BaseOps, 171*0fca6ea1SDimitry Andric int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, 1725f757f3fSDimitry Andric const TargetRegisterInfo *TRI) const override; 1735f757f3fSDimitry Andric 1745f757f3fSDimitry Andric bool shouldClusterMemOps(ArrayRef<const MachineOperand *> BaseOps1, 1755f757f3fSDimitry Andric int64_t Offset1, bool OffsetIsScalable1, 1765f757f3fSDimitry Andric ArrayRef<const MachineOperand *> BaseOps2, 1775f757f3fSDimitry Andric int64_t Offset2, bool OffsetIsScalable2, 1785f757f3fSDimitry Andric unsigned ClusterSize, 1795f757f3fSDimitry Andric unsigned NumBytes) const override; 1805f757f3fSDimitry Andric 181480093f4SDimitry Andric bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, 182480093f4SDimitry Andric const MachineOperand *&BaseOp, 183*0fca6ea1SDimitry Andric int64_t &Offset, LocationSize &Width, 184480093f4SDimitry Andric const TargetRegisterInfo *TRI) const; 185480093f4SDimitry Andric 186480093f4SDimitry Andric bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, 187480093f4SDimitry Andric const MachineInstr &MIb) const override; 188480093f4SDimitry Andric 189480093f4SDimitry Andric 190480093f4SDimitry Andric std::pair<unsigned, unsigned> 191480093f4SDimitry Andric decomposeMachineOperandsTargetFlags(unsigned TF) const override; 192480093f4SDimitry Andric 193480093f4SDimitry Andric ArrayRef<std::pair<unsigned, const char *>> 194480093f4SDimitry Andric getSerializableDirectMachineOperandTargetFlags() const override; 195480093f4SDimitry Andric 196480093f4SDimitry Andric // Return true if the function can safely be outlined from. 197972a253aSDimitry Andric bool isFunctionSafeToOutlineFrom(MachineFunction &MF, 198480093f4SDimitry Andric bool OutlineFromLinkOnceODRs) const override; 199480093f4SDimitry Andric 200480093f4SDimitry Andric // Return true if MBB is safe to outline from, and return any target-specific 201480093f4SDimitry Andric // information in Flags. 202972a253aSDimitry Andric bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, 203480093f4SDimitry Andric unsigned &Flags) const override; 204480093f4SDimitry Andric 20581ad6265SDimitry Andric bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override; 20681ad6265SDimitry Andric 207480093f4SDimitry Andric // Calculate target-specific information for a set of outlining candidates. 20806c3fb27SDimitry Andric std::optional<outliner::OutlinedFunction> getOutliningCandidateInfo( 209480093f4SDimitry Andric std::vector<outliner::Candidate> &RepeatedSequenceLocs) const override; 210480093f4SDimitry Andric 211480093f4SDimitry Andric // Return if/how a given MachineInstr should be outlined. 21206c3fb27SDimitry Andric virtual outliner::InstrType 21306c3fb27SDimitry Andric getOutliningTypeImpl(MachineBasicBlock::iterator &MBBI, 214480093f4SDimitry Andric unsigned Flags) const override; 215480093f4SDimitry Andric 216480093f4SDimitry Andric // Insert a custom frame for outlined functions. 217972a253aSDimitry Andric void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF, 218480093f4SDimitry Andric const outliner::OutlinedFunction &OF) const override; 219480093f4SDimitry Andric 220480093f4SDimitry Andric // Insert a call to an outlined function into a given basic block. 221972a253aSDimitry Andric MachineBasicBlock::iterator 222480093f4SDimitry Andric insertOutlinedCall(Module &M, MachineBasicBlock &MBB, 223480093f4SDimitry Andric MachineBasicBlock::iterator &It, MachineFunction &MF, 22481ad6265SDimitry Andric outliner::Candidate &C) const override; 225fe6060f1SDimitry Andric 2265f757f3fSDimitry Andric std::optional<RegImmPair> isAddImmediate(const MachineInstr &MI, 2275f757f3fSDimitry Andric Register Reg) const override; 2285f757f3fSDimitry Andric 229fe6060f1SDimitry Andric bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, 230fe6060f1SDimitry Andric unsigned &SrcOpIdx2) const override; 231fe6060f1SDimitry Andric MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI, 232fe6060f1SDimitry Andric unsigned OpIdx1, 233fe6060f1SDimitry Andric unsigned OpIdx2) const override; 234fe6060f1SDimitry Andric 235349cc55cSDimitry Andric MachineInstr *convertToThreeAddress(MachineInstr &MI, LiveVariables *LV, 236349cc55cSDimitry Andric LiveIntervals *LIS) const override; 237fe6060f1SDimitry Andric 23881ad6265SDimitry Andric // MIR printer helper function to annotate Operands with a comment. 23981ad6265SDimitry Andric std::string 24081ad6265SDimitry Andric createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, 24181ad6265SDimitry Andric unsigned OpIdx, 24281ad6265SDimitry Andric const TargetRegisterInfo *TRI) const override; 24381ad6265SDimitry Andric 244*0fca6ea1SDimitry Andric /// Generate code to multiply the value in DestReg by Amt - handles all 245*0fca6ea1SDimitry Andric /// the common optimizations for this idiom, and supports fallback for 246*0fca6ea1SDimitry Andric /// subtargets which don't support multiply instructions. 247*0fca6ea1SDimitry Andric void mulImm(MachineFunction &MF, MachineBasicBlock &MBB, 248*0fca6ea1SDimitry Andric MachineBasicBlock::iterator II, const DebugLoc &DL, 249*0fca6ea1SDimitry Andric Register DestReg, uint32_t Amt, MachineInstr::MIFlag Flag) const; 250bdd1243dSDimitry Andric useMachineCombiner()251bdd1243dSDimitry Andric bool useMachineCombiner() const override { return true; } 252bdd1243dSDimitry Andric 25306c3fb27SDimitry Andric MachineTraceStrategy getMachineCombinerTraceStrategy() const override; 25406c3fb27SDimitry Andric 255*0fca6ea1SDimitry Andric CombinerObjective getCombinerObjective(unsigned Pattern) const override; 256*0fca6ea1SDimitry Andric 257*0fca6ea1SDimitry Andric bool getMachineCombinerPatterns(MachineInstr &Root, 258*0fca6ea1SDimitry Andric SmallVectorImpl<unsigned> &Patterns, 259bdd1243dSDimitry Andric bool DoRegPressureReduce) const override; 260bdd1243dSDimitry Andric 261bdd1243dSDimitry Andric void 262*0fca6ea1SDimitry Andric finalizeInsInstrs(MachineInstr &Root, unsigned &Pattern, 263bdd1243dSDimitry Andric SmallVectorImpl<MachineInstr *> &InsInstrs) const override; 264bdd1243dSDimitry Andric 265bdd1243dSDimitry Andric void genAlternativeCodeSequence( 266*0fca6ea1SDimitry Andric MachineInstr &Root, unsigned Pattern, 267bdd1243dSDimitry Andric SmallVectorImpl<MachineInstr *> &InsInstrs, 268bdd1243dSDimitry Andric SmallVectorImpl<MachineInstr *> &DelInstrs, 269bdd1243dSDimitry Andric DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const override; 270bdd1243dSDimitry Andric 271*0fca6ea1SDimitry Andric bool hasReassociableOperands(const MachineInstr &Inst, 272*0fca6ea1SDimitry Andric const MachineBasicBlock *MBB) const override; 273*0fca6ea1SDimitry Andric 274bdd1243dSDimitry Andric bool hasReassociableSibling(const MachineInstr &Inst, 275bdd1243dSDimitry Andric bool &Commuted) const override; 276bdd1243dSDimitry Andric 277bdd1243dSDimitry Andric bool isAssociativeAndCommutative(const MachineInstr &Inst, 278bdd1243dSDimitry Andric bool Invert) const override; 279bdd1243dSDimitry Andric 280bdd1243dSDimitry Andric std::optional<unsigned> getInverseOpcode(unsigned Opcode) const override; 281bdd1243dSDimitry Andric 282*0fca6ea1SDimitry Andric void getReassociateOperandIndices( 283*0fca6ea1SDimitry Andric const MachineInstr &Root, unsigned Pattern, 284*0fca6ea1SDimitry Andric std::array<unsigned, 5> &OperandIndices) const override; 285*0fca6ea1SDimitry Andric 28606c3fb27SDimitry Andric ArrayRef<std::pair<MachineMemOperand::Flags, const char *>> 28706c3fb27SDimitry Andric getSerializableMachineMemOperandTargetFlags() const override; 288fe6060f1SDimitry Andric getUndefInitOpcode(unsigned RegClassID)289*0fca6ea1SDimitry Andric unsigned getUndefInitOpcode(unsigned RegClassID) const override { 290*0fca6ea1SDimitry Andric switch (RegClassID) { 291*0fca6ea1SDimitry Andric case RISCV::VRRegClassID: 292*0fca6ea1SDimitry Andric return RISCV::PseudoRVVInitUndefM1; 293*0fca6ea1SDimitry Andric case RISCV::VRM2RegClassID: 294*0fca6ea1SDimitry Andric return RISCV::PseudoRVVInitUndefM2; 295*0fca6ea1SDimitry Andric case RISCV::VRM4RegClassID: 296*0fca6ea1SDimitry Andric return RISCV::PseudoRVVInitUndefM4; 297*0fca6ea1SDimitry Andric case RISCV::VRM8RegClassID: 298*0fca6ea1SDimitry Andric return RISCV::PseudoRVVInitUndefM8; 299*0fca6ea1SDimitry Andric default: 300*0fca6ea1SDimitry Andric llvm_unreachable("Unexpected register class."); 301*0fca6ea1SDimitry Andric } 302*0fca6ea1SDimitry Andric } 303*0fca6ea1SDimitry Andric 3048bcb0991SDimitry Andric protected: 3058bcb0991SDimitry Andric const RISCVSubtarget &STI; 30606c3fb27SDimitry Andric 30706c3fb27SDimitry Andric private: 30806c3fb27SDimitry Andric unsigned getInstBundleLength(const MachineInstr &MI) const; 309*0fca6ea1SDimitry Andric 310*0fca6ea1SDimitry Andric bool isVectorAssociativeAndCommutative(const MachineInstr &MI, 311*0fca6ea1SDimitry Andric bool Invert = false) const; 312*0fca6ea1SDimitry Andric bool areRVVInstsReassociable(const MachineInstr &MI1, 313*0fca6ea1SDimitry Andric const MachineInstr &MI2) const; 314*0fca6ea1SDimitry Andric bool hasReassociableVectorSibling(const MachineInstr &Inst, 315*0fca6ea1SDimitry Andric bool &Commuted) const; 3160b57cec5SDimitry Andric }; 3175ffd83dbSDimitry Andric 318349cc55cSDimitry Andric namespace RISCV { 3190eae32dcSDimitry Andric 320fcaf7f86SDimitry Andric // Returns true if this is the sext.w pattern, addiw rd, rs1, 0. 321fcaf7f86SDimitry Andric bool isSEXT_W(const MachineInstr &MI); 322fcaf7f86SDimitry Andric bool isZEXT_W(const MachineInstr &MI); 323fcaf7f86SDimitry Andric bool isZEXT_B(const MachineInstr &MI); 324fcaf7f86SDimitry Andric 32581ad6265SDimitry Andric // Returns true if the given MI is an RVV instruction opcode for which we may 32681ad6265SDimitry Andric // expect to see a FrameIndex operand. 32781ad6265SDimitry Andric bool isRVVSpill(const MachineInstr &MI); 32881ad6265SDimitry Andric 329bdd1243dSDimitry Andric std::optional<std::pair<unsigned, unsigned>> 330bdd1243dSDimitry Andric isRVVSpillForZvlsseg(unsigned Opcode); 33181ad6265SDimitry Andric 33281ad6265SDimitry Andric bool isFaultFirstLoad(const MachineInstr &MI); 33381ad6265SDimitry Andric 3340eae32dcSDimitry Andric // Implemented in RISCVGenInstrInfo.inc 3350eae32dcSDimitry Andric int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex); 3360eae32dcSDimitry Andric 337bdd1243dSDimitry Andric // Return true if both input instructions have equal rounding mode. If at least 338bdd1243dSDimitry Andric // one of the instructions does not have rounding mode, false will be returned. 339bdd1243dSDimitry Andric bool hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2); 340bdd1243dSDimitry Andric 3415f757f3fSDimitry Andric // If \p Opcode is a .vx vector instruction, returns the lower number of bits 3425f757f3fSDimitry Andric // that are used from the scalar .x operand for a given \p Log2SEW. Otherwise 3435f757f3fSDimitry Andric // returns null. 3445f757f3fSDimitry Andric std::optional<unsigned> getVectorLowDemandedScalarBits(uint16_t Opcode, 3455f757f3fSDimitry Andric unsigned Log2SEW); 3465f757f3fSDimitry Andric 3475f757f3fSDimitry Andric // Returns the MC opcode of RVV pseudo instruction. 3485f757f3fSDimitry Andric unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode); 3495f757f3fSDimitry Andric 350349cc55cSDimitry Andric // Special immediate for AVL operand of V pseudo instructions to indicate VLMax. 351349cc55cSDimitry Andric static constexpr int64_t VLMaxSentinel = -1LL; 352bdd1243dSDimitry Andric 35306c3fb27SDimitry Andric // Mask assignments for floating-point 35406c3fb27SDimitry Andric static constexpr unsigned FPMASK_Negative_Infinity = 0x001; 35506c3fb27SDimitry Andric static constexpr unsigned FPMASK_Negative_Normal = 0x002; 35606c3fb27SDimitry Andric static constexpr unsigned FPMASK_Negative_Subnormal = 0x004; 35706c3fb27SDimitry Andric static constexpr unsigned FPMASK_Negative_Zero = 0x008; 35806c3fb27SDimitry Andric static constexpr unsigned FPMASK_Positive_Zero = 0x010; 35906c3fb27SDimitry Andric static constexpr unsigned FPMASK_Positive_Subnormal = 0x020; 36006c3fb27SDimitry Andric static constexpr unsigned FPMASK_Positive_Normal = 0x040; 36106c3fb27SDimitry Andric static constexpr unsigned FPMASK_Positive_Infinity = 0x080; 36206c3fb27SDimitry Andric static constexpr unsigned FPMASK_Signaling_NaN = 0x100; 36306c3fb27SDimitry Andric static constexpr unsigned FPMASK_Quiet_NaN = 0x200; 364349cc55cSDimitry Andric } // namespace RISCV 365349cc55cSDimitry Andric 366fe6060f1SDimitry Andric namespace RISCVVPseudosTable { 367fe6060f1SDimitry Andric 368fe6060f1SDimitry Andric struct PseudoInfo { 369fe6060f1SDimitry Andric uint16_t Pseudo; 370fe6060f1SDimitry Andric uint16_t BaseInstr; 371fe6060f1SDimitry Andric }; 372fe6060f1SDimitry Andric 373fe6060f1SDimitry Andric #define GET_RISCVVPseudosTable_DECL 374fe6060f1SDimitry Andric #include "RISCVGenSearchableTables.inc" 375fe6060f1SDimitry Andric 376fe6060f1SDimitry Andric } // end namespace RISCVVPseudosTable 377fe6060f1SDimitry Andric 378*0fca6ea1SDimitry Andric namespace RISCV { 379*0fca6ea1SDimitry Andric 380*0fca6ea1SDimitry Andric struct RISCVMaskedPseudoInfo { 381*0fca6ea1SDimitry Andric uint16_t MaskedPseudo; 382*0fca6ea1SDimitry Andric uint16_t UnmaskedPseudo; 383*0fca6ea1SDimitry Andric uint8_t MaskOpIdx; 384*0fca6ea1SDimitry Andric uint8_t ActiveElementsAffectResult : 1; 385*0fca6ea1SDimitry Andric }; 386*0fca6ea1SDimitry Andric #define GET_RISCVMaskedPseudosTable_DECL 387*0fca6ea1SDimitry Andric #include "RISCVGenSearchableTables.inc" 388*0fca6ea1SDimitry Andric } // end namespace RISCV 389*0fca6ea1SDimitry Andric 3905ffd83dbSDimitry Andric } // end namespace llvm 3910b57cec5SDimitry Andric #endif 392