1*0b57cec5SDimitry Andric //===- HexagonInstrInfo.h - Hexagon Instruction Information -----*- C++ -*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file contains the Hexagon implementation of the TargetInstrInfo class. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONINSTRINFO_H 14*0b57cec5SDimitry Andric #define LLVM_LIB_TARGET_HEXAGON_HEXAGONINSTRINFO_H 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric #include "MCTargetDesc/HexagonBaseInfo.h" 17*0b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 18*0b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 19*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 20*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 21*0b57cec5SDimitry Andric #include "llvm/CodeGen/ValueTypes.h" 22*0b57cec5SDimitry Andric #include "llvm/Support/MachineValueType.h" 23*0b57cec5SDimitry Andric #include <cstdint> 24*0b57cec5SDimitry Andric #include <vector> 25*0b57cec5SDimitry Andric 26*0b57cec5SDimitry Andric #define GET_INSTRINFO_HEADER 27*0b57cec5SDimitry Andric #include "HexagonGenInstrInfo.inc" 28*0b57cec5SDimitry Andric 29*0b57cec5SDimitry Andric namespace llvm { 30*0b57cec5SDimitry Andric 31*0b57cec5SDimitry Andric class HexagonSubtarget; 32*0b57cec5SDimitry Andric class MachineBranchProbabilityInfo; 33*0b57cec5SDimitry Andric class MachineFunction; 34*0b57cec5SDimitry Andric class MachineInstr; 35*0b57cec5SDimitry Andric class MachineOperand; 36*0b57cec5SDimitry Andric class TargetRegisterInfo; 37*0b57cec5SDimitry Andric 38*0b57cec5SDimitry Andric class HexagonInstrInfo : public HexagonGenInstrInfo { 39*0b57cec5SDimitry Andric const HexagonSubtarget &Subtarget; 40*0b57cec5SDimitry Andric 41*0b57cec5SDimitry Andric enum BundleAttribute { 42*0b57cec5SDimitry Andric memShufDisabledMask = 0x4 43*0b57cec5SDimitry Andric }; 44*0b57cec5SDimitry Andric 45*0b57cec5SDimitry Andric virtual void anchor(); 46*0b57cec5SDimitry Andric 47*0b57cec5SDimitry Andric public: 48*0b57cec5SDimitry Andric explicit HexagonInstrInfo(HexagonSubtarget &ST); 49*0b57cec5SDimitry Andric 50*0b57cec5SDimitry Andric /// TargetInstrInfo overrides. 51*0b57cec5SDimitry Andric 52*0b57cec5SDimitry Andric /// If the specified machine instruction is a direct 53*0b57cec5SDimitry Andric /// load from a stack slot, return the virtual or physical register number of 54*0b57cec5SDimitry Andric /// the destination along with the FrameIndex of the loaded stack slot. If 55*0b57cec5SDimitry Andric /// not, return 0. This predicate must return 0 if the instruction has 56*0b57cec5SDimitry Andric /// any side effects other than loading from the stack slot. 57*0b57cec5SDimitry Andric unsigned isLoadFromStackSlot(const MachineInstr &MI, 58*0b57cec5SDimitry Andric int &FrameIndex) const override; 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andric /// If the specified machine instruction is a direct 61*0b57cec5SDimitry Andric /// store to a stack slot, return the virtual or physical register number of 62*0b57cec5SDimitry Andric /// the source reg along with the FrameIndex of the loaded stack slot. If 63*0b57cec5SDimitry Andric /// not, return 0. This predicate must return 0 if the instruction has 64*0b57cec5SDimitry Andric /// any side effects other than storing to the stack slot. 65*0b57cec5SDimitry Andric unsigned isStoreToStackSlot(const MachineInstr &MI, 66*0b57cec5SDimitry Andric int &FrameIndex) const override; 67*0b57cec5SDimitry Andric 68*0b57cec5SDimitry Andric /// Check if the instruction or the bundle of instructions has 69*0b57cec5SDimitry Andric /// load from stack slots. Return the frameindex and machine memory operand 70*0b57cec5SDimitry Andric /// if true. 71*0b57cec5SDimitry Andric bool hasLoadFromStackSlot( 72*0b57cec5SDimitry Andric const MachineInstr &MI, 73*0b57cec5SDimitry Andric SmallVectorImpl<const MachineMemOperand *> &Accesses) const override; 74*0b57cec5SDimitry Andric 75*0b57cec5SDimitry Andric /// Check if the instruction or the bundle of instructions has 76*0b57cec5SDimitry Andric /// store to stack slots. Return the frameindex and machine memory operand 77*0b57cec5SDimitry Andric /// if true. 78*0b57cec5SDimitry Andric bool hasStoreToStackSlot( 79*0b57cec5SDimitry Andric const MachineInstr &MI, 80*0b57cec5SDimitry Andric SmallVectorImpl<const MachineMemOperand *> &Accesses) const override; 81*0b57cec5SDimitry Andric 82*0b57cec5SDimitry Andric /// Analyze the branching code at the end of MBB, returning 83*0b57cec5SDimitry Andric /// true if it cannot be understood (e.g. it's a switch dispatch or isn't 84*0b57cec5SDimitry Andric /// implemented for a target). Upon success, this returns false and returns 85*0b57cec5SDimitry Andric /// with the following information in various cases: 86*0b57cec5SDimitry Andric /// 87*0b57cec5SDimitry Andric /// 1. If this block ends with no branches (it just falls through to its succ) 88*0b57cec5SDimitry Andric /// just return false, leaving TBB/FBB null. 89*0b57cec5SDimitry Andric /// 2. If this block ends with only an unconditional branch, it sets TBB to be 90*0b57cec5SDimitry Andric /// the destination block. 91*0b57cec5SDimitry Andric /// 3. If this block ends with a conditional branch and it falls through to a 92*0b57cec5SDimitry Andric /// successor block, it sets TBB to be the branch destination block and a 93*0b57cec5SDimitry Andric /// list of operands that evaluate the condition. These operands can be 94*0b57cec5SDimitry Andric /// passed to other TargetInstrInfo methods to create new branches. 95*0b57cec5SDimitry Andric /// 4. If this block ends with a conditional branch followed by an 96*0b57cec5SDimitry Andric /// unconditional branch, it returns the 'true' destination in TBB, the 97*0b57cec5SDimitry Andric /// 'false' destination in FBB, and a list of operands that evaluate the 98*0b57cec5SDimitry Andric /// condition. These operands can be passed to other TargetInstrInfo 99*0b57cec5SDimitry Andric /// methods to create new branches. 100*0b57cec5SDimitry Andric /// 101*0b57cec5SDimitry Andric /// Note that removeBranch and insertBranch must be implemented to support 102*0b57cec5SDimitry Andric /// cases where this method returns success. 103*0b57cec5SDimitry Andric /// 104*0b57cec5SDimitry Andric /// If AllowModify is true, then this routine is allowed to modify the basic 105*0b57cec5SDimitry Andric /// block (e.g. delete instructions after the unconditional branch). 106*0b57cec5SDimitry Andric bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 107*0b57cec5SDimitry Andric MachineBasicBlock *&FBB, 108*0b57cec5SDimitry Andric SmallVectorImpl<MachineOperand> &Cond, 109*0b57cec5SDimitry Andric bool AllowModify) const override; 110*0b57cec5SDimitry Andric 111*0b57cec5SDimitry Andric /// Remove the branching code at the end of the specific MBB. 112*0b57cec5SDimitry Andric /// This is only invoked in cases where AnalyzeBranch returns success. It 113*0b57cec5SDimitry Andric /// returns the number of instructions that were removed. 114*0b57cec5SDimitry Andric unsigned removeBranch(MachineBasicBlock &MBB, 115*0b57cec5SDimitry Andric int *BytesRemoved = nullptr) const override; 116*0b57cec5SDimitry Andric 117*0b57cec5SDimitry Andric /// Insert branch code into the end of the specified MachineBasicBlock. 118*0b57cec5SDimitry Andric /// The operands to this method are the same as those 119*0b57cec5SDimitry Andric /// returned by AnalyzeBranch. This is only invoked in cases where 120*0b57cec5SDimitry Andric /// AnalyzeBranch returns success. It returns the number of instructions 121*0b57cec5SDimitry Andric /// inserted. 122*0b57cec5SDimitry Andric /// 123*0b57cec5SDimitry Andric /// It is also invoked by tail merging to add unconditional branches in 124*0b57cec5SDimitry Andric /// cases where AnalyzeBranch doesn't apply because there was no original 125*0b57cec5SDimitry Andric /// branch to analyze. At least this much must be implemented, else tail 126*0b57cec5SDimitry Andric /// merging needs to be disabled. 127*0b57cec5SDimitry Andric unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 128*0b57cec5SDimitry Andric MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, 129*0b57cec5SDimitry Andric const DebugLoc &DL, 130*0b57cec5SDimitry Andric int *BytesAdded = nullptr) const override; 131*0b57cec5SDimitry Andric 132*0b57cec5SDimitry Andric /// Analyze the loop code, return true if it cannot be understood. Upon 133*0b57cec5SDimitry Andric /// success, this function returns false and returns information about the 134*0b57cec5SDimitry Andric /// induction variable and compare instruction used at the end. 135*0b57cec5SDimitry Andric bool analyzeLoop(MachineLoop &L, MachineInstr *&IndVarInst, 136*0b57cec5SDimitry Andric MachineInstr *&CmpInst) const override; 137*0b57cec5SDimitry Andric 138*0b57cec5SDimitry Andric /// Generate code to reduce the loop iteration by one and check if the loop 139*0b57cec5SDimitry Andric /// is finished. Return the value/register of the new loop count. We need 140*0b57cec5SDimitry Andric /// this function when peeling off one or more iterations of a loop. This 141*0b57cec5SDimitry Andric /// function assumes the nth iteration is peeled first. 142*0b57cec5SDimitry Andric unsigned reduceLoopCount(MachineBasicBlock &MBB, MachineBasicBlock &PreHeader, 143*0b57cec5SDimitry Andric MachineInstr *IndVar, MachineInstr &Cmp, 144*0b57cec5SDimitry Andric SmallVectorImpl<MachineOperand> &Cond, 145*0b57cec5SDimitry Andric SmallVectorImpl<MachineInstr *> &PrevInsts, 146*0b57cec5SDimitry Andric unsigned Iter, unsigned MaxIter) const override; 147*0b57cec5SDimitry Andric 148*0b57cec5SDimitry Andric /// Return true if it's profitable to predicate 149*0b57cec5SDimitry Andric /// instructions with accumulated instruction latency of "NumCycles" 150*0b57cec5SDimitry Andric /// of the specified basic block, where the probability of the instructions 151*0b57cec5SDimitry Andric /// being executed is given by Probability, and Confidence is a measure 152*0b57cec5SDimitry Andric /// of our confidence that it will be properly predicted. 153*0b57cec5SDimitry Andric bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, 154*0b57cec5SDimitry Andric unsigned ExtraPredCycles, 155*0b57cec5SDimitry Andric BranchProbability Probability) const override; 156*0b57cec5SDimitry Andric 157*0b57cec5SDimitry Andric /// Second variant of isProfitableToIfCvt. This one 158*0b57cec5SDimitry Andric /// checks for the case where two basic blocks from true and false path 159*0b57cec5SDimitry Andric /// of a if-then-else (diamond) are predicated on mutally exclusive 160*0b57cec5SDimitry Andric /// predicates, where the probability of the true path being taken is given 161*0b57cec5SDimitry Andric /// by Probability, and Confidence is a measure of our confidence that it 162*0b57cec5SDimitry Andric /// will be properly predicted. 163*0b57cec5SDimitry Andric bool isProfitableToIfCvt(MachineBasicBlock &TMBB, 164*0b57cec5SDimitry Andric unsigned NumTCycles, unsigned ExtraTCycles, 165*0b57cec5SDimitry Andric MachineBasicBlock &FMBB, 166*0b57cec5SDimitry Andric unsigned NumFCycles, unsigned ExtraFCycles, 167*0b57cec5SDimitry Andric BranchProbability Probability) const override; 168*0b57cec5SDimitry Andric 169*0b57cec5SDimitry Andric /// Return true if it's profitable for if-converter to duplicate instructions 170*0b57cec5SDimitry Andric /// of specified accumulated instruction latencies in the specified MBB to 171*0b57cec5SDimitry Andric /// enable if-conversion. 172*0b57cec5SDimitry Andric /// The probability of the instructions being executed is given by 173*0b57cec5SDimitry Andric /// Probability, and Confidence is a measure of our confidence that it 174*0b57cec5SDimitry Andric /// will be properly predicted. 175*0b57cec5SDimitry Andric bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, 176*0b57cec5SDimitry Andric BranchProbability Probability) const override; 177*0b57cec5SDimitry Andric 178*0b57cec5SDimitry Andric /// Emit instructions to copy a pair of physical registers. 179*0b57cec5SDimitry Andric /// 180*0b57cec5SDimitry Andric /// This function should support copies within any legal register class as 181*0b57cec5SDimitry Andric /// well as any cross-class copies created during instruction selection. 182*0b57cec5SDimitry Andric /// 183*0b57cec5SDimitry Andric /// The source and destination registers may overlap, which may require a 184*0b57cec5SDimitry Andric /// careful implementation when multiple copy instructions are required for 185*0b57cec5SDimitry Andric /// large registers. See for example the ARM target. 186*0b57cec5SDimitry Andric void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 187*0b57cec5SDimitry Andric const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, 188*0b57cec5SDimitry Andric bool KillSrc) const override; 189*0b57cec5SDimitry Andric 190*0b57cec5SDimitry Andric /// Store the specified register of the given register class to the specified 191*0b57cec5SDimitry Andric /// stack frame index. The store instruction is to be added to the given 192*0b57cec5SDimitry Andric /// machine basic block before the specified machine instruction. If isKill 193*0b57cec5SDimitry Andric /// is true, the register operand is the last use and must be marked kill. 194*0b57cec5SDimitry Andric void storeRegToStackSlot(MachineBasicBlock &MBB, 195*0b57cec5SDimitry Andric MachineBasicBlock::iterator MBBI, 196*0b57cec5SDimitry Andric unsigned SrcReg, bool isKill, int FrameIndex, 197*0b57cec5SDimitry Andric const TargetRegisterClass *RC, 198*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI) const override; 199*0b57cec5SDimitry Andric 200*0b57cec5SDimitry Andric /// Load the specified register of the given register class from the specified 201*0b57cec5SDimitry Andric /// stack frame index. The load instruction is to be added to the given 202*0b57cec5SDimitry Andric /// machine basic block before the specified machine instruction. 203*0b57cec5SDimitry Andric void loadRegFromStackSlot(MachineBasicBlock &MBB, 204*0b57cec5SDimitry Andric MachineBasicBlock::iterator MBBI, 205*0b57cec5SDimitry Andric unsigned DestReg, int FrameIndex, 206*0b57cec5SDimitry Andric const TargetRegisterClass *RC, 207*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI) const override; 208*0b57cec5SDimitry Andric 209*0b57cec5SDimitry Andric /// This function is called for all pseudo instructions 210*0b57cec5SDimitry Andric /// that remain after register allocation. Many pseudo instructions are 211*0b57cec5SDimitry Andric /// created to help register allocation. This is the place to convert them 212*0b57cec5SDimitry Andric /// into real instructions. The target can edit MI in place, or it can insert 213*0b57cec5SDimitry Andric /// new instructions and erase MI. The function should return true if 214*0b57cec5SDimitry Andric /// anything was changed. 215*0b57cec5SDimitry Andric bool expandPostRAPseudo(MachineInstr &MI) const override; 216*0b57cec5SDimitry Andric 217*0b57cec5SDimitry Andric /// Get the base register and byte offset of a load/store instr. 218*0b57cec5SDimitry Andric bool getMemOperandWithOffset(const MachineInstr &LdSt, 219*0b57cec5SDimitry Andric const MachineOperand *&BaseOp, 220*0b57cec5SDimitry Andric int64_t &Offset, 221*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI) const override; 222*0b57cec5SDimitry Andric 223*0b57cec5SDimitry Andric /// Reverses the branch condition of the specified condition list, 224*0b57cec5SDimitry Andric /// returning false on success and true if it cannot be reversed. 225*0b57cec5SDimitry Andric bool reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) 226*0b57cec5SDimitry Andric const override; 227*0b57cec5SDimitry Andric 228*0b57cec5SDimitry Andric /// Insert a noop into the instruction stream at the specified point. 229*0b57cec5SDimitry Andric void insertNoop(MachineBasicBlock &MBB, 230*0b57cec5SDimitry Andric MachineBasicBlock::iterator MI) const override; 231*0b57cec5SDimitry Andric 232*0b57cec5SDimitry Andric /// Returns true if the instruction is already predicated. 233*0b57cec5SDimitry Andric bool isPredicated(const MachineInstr &MI) const override; 234*0b57cec5SDimitry Andric 235*0b57cec5SDimitry Andric /// Return true for post-incremented instructions. 236*0b57cec5SDimitry Andric bool isPostIncrement(const MachineInstr &MI) const override; 237*0b57cec5SDimitry Andric 238*0b57cec5SDimitry Andric /// Convert the instruction into a predicated instruction. 239*0b57cec5SDimitry Andric /// It returns true if the operation was successful. 240*0b57cec5SDimitry Andric bool PredicateInstruction(MachineInstr &MI, 241*0b57cec5SDimitry Andric ArrayRef<MachineOperand> Cond) const override; 242*0b57cec5SDimitry Andric 243*0b57cec5SDimitry Andric /// Returns true if the first specified predicate 244*0b57cec5SDimitry Andric /// subsumes the second, e.g. GE subsumes GT. 245*0b57cec5SDimitry Andric bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1, 246*0b57cec5SDimitry Andric ArrayRef<MachineOperand> Pred2) const override; 247*0b57cec5SDimitry Andric 248*0b57cec5SDimitry Andric /// If the specified instruction defines any predicate 249*0b57cec5SDimitry Andric /// or condition code register(s) used for predication, returns true as well 250*0b57cec5SDimitry Andric /// as the definition predicate(s) by reference. 251*0b57cec5SDimitry Andric bool DefinesPredicate(MachineInstr &MI, 252*0b57cec5SDimitry Andric std::vector<MachineOperand> &Pred) const override; 253*0b57cec5SDimitry Andric 254*0b57cec5SDimitry Andric /// Return true if the specified instruction can be predicated. 255*0b57cec5SDimitry Andric /// By default, this returns true for every instruction with a 256*0b57cec5SDimitry Andric /// PredicateOperand. 257*0b57cec5SDimitry Andric bool isPredicable(const MachineInstr &MI) const override; 258*0b57cec5SDimitry Andric 259*0b57cec5SDimitry Andric /// Test if the given instruction should be considered a scheduling boundary. 260*0b57cec5SDimitry Andric /// This primarily includes labels and terminators. 261*0b57cec5SDimitry Andric bool isSchedulingBoundary(const MachineInstr &MI, 262*0b57cec5SDimitry Andric const MachineBasicBlock *MBB, 263*0b57cec5SDimitry Andric const MachineFunction &MF) const override; 264*0b57cec5SDimitry Andric 265*0b57cec5SDimitry Andric /// Measure the specified inline asm to determine an approximation of its 266*0b57cec5SDimitry Andric /// length. 267*0b57cec5SDimitry Andric unsigned getInlineAsmLength( 268*0b57cec5SDimitry Andric const char *Str, 269*0b57cec5SDimitry Andric const MCAsmInfo &MAI, 270*0b57cec5SDimitry Andric const TargetSubtargetInfo *STI = nullptr) const override; 271*0b57cec5SDimitry Andric 272*0b57cec5SDimitry Andric /// Allocate and return a hazard recognizer to use for this target when 273*0b57cec5SDimitry Andric /// scheduling the machine instructions after register allocation. 274*0b57cec5SDimitry Andric ScheduleHazardRecognizer* 275*0b57cec5SDimitry Andric CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, 276*0b57cec5SDimitry Andric const ScheduleDAG *DAG) const override; 277*0b57cec5SDimitry Andric 278*0b57cec5SDimitry Andric /// For a comparison instruction, return the source registers 279*0b57cec5SDimitry Andric /// in SrcReg and SrcReg2 if having two register operands, and the value it 280*0b57cec5SDimitry Andric /// compares against in CmpValue. Return true if the comparison instruction 281*0b57cec5SDimitry Andric /// can be analyzed. 282*0b57cec5SDimitry Andric bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, 283*0b57cec5SDimitry Andric unsigned &SrcReg2, int &Mask, int &Value) const override; 284*0b57cec5SDimitry Andric 285*0b57cec5SDimitry Andric /// Compute the instruction latency of a given instruction. 286*0b57cec5SDimitry Andric /// If the instruction has higher cost when predicated, it's returned via 287*0b57cec5SDimitry Andric /// PredCost. 288*0b57cec5SDimitry Andric unsigned getInstrLatency(const InstrItineraryData *ItinData, 289*0b57cec5SDimitry Andric const MachineInstr &MI, 290*0b57cec5SDimitry Andric unsigned *PredCost = nullptr) const override; 291*0b57cec5SDimitry Andric 292*0b57cec5SDimitry Andric /// Create machine specific model for scheduling. 293*0b57cec5SDimitry Andric DFAPacketizer * 294*0b57cec5SDimitry Andric CreateTargetScheduleState(const TargetSubtargetInfo &STI) const override; 295*0b57cec5SDimitry Andric 296*0b57cec5SDimitry Andric // Sometimes, it is possible for the target 297*0b57cec5SDimitry Andric // to tell, even without aliasing information, that two MIs access different 298*0b57cec5SDimitry Andric // memory addresses. This function returns true if two MIs access different 299*0b57cec5SDimitry Andric // memory addresses and false otherwise. 300*0b57cec5SDimitry Andric bool 301*0b57cec5SDimitry Andric areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, 302*0b57cec5SDimitry Andric const MachineInstr &MIb, 303*0b57cec5SDimitry Andric AliasAnalysis *AA = nullptr) const override; 304*0b57cec5SDimitry Andric 305*0b57cec5SDimitry Andric /// For instructions with a base and offset, return the position of the 306*0b57cec5SDimitry Andric /// base register and offset operands. 307*0b57cec5SDimitry Andric bool getBaseAndOffsetPosition(const MachineInstr &MI, unsigned &BasePos, 308*0b57cec5SDimitry Andric unsigned &OffsetPos) const override; 309*0b57cec5SDimitry Andric 310*0b57cec5SDimitry Andric /// If the instruction is an increment of a constant value, return the amount. 311*0b57cec5SDimitry Andric bool getIncrementValue(const MachineInstr &MI, int &Value) const override; 312*0b57cec5SDimitry Andric 313*0b57cec5SDimitry Andric /// getOperandLatency - Compute and return the use operand latency of a given 314*0b57cec5SDimitry Andric /// pair of def and use. 315*0b57cec5SDimitry Andric /// In most cases, the static scheduling itinerary was enough to determine the 316*0b57cec5SDimitry Andric /// operand latency. But it may not be possible for instructions with variable 317*0b57cec5SDimitry Andric /// number of defs / uses. 318*0b57cec5SDimitry Andric /// 319*0b57cec5SDimitry Andric /// This is a raw interface to the itinerary that may be directly overriden by 320*0b57cec5SDimitry Andric /// a target. Use computeOperandLatency to get the best estimate of latency. 321*0b57cec5SDimitry Andric int getOperandLatency(const InstrItineraryData *ItinData, 322*0b57cec5SDimitry Andric const MachineInstr &DefMI, unsigned DefIdx, 323*0b57cec5SDimitry Andric const MachineInstr &UseMI, 324*0b57cec5SDimitry Andric unsigned UseIdx) const override; 325*0b57cec5SDimitry Andric 326*0b57cec5SDimitry Andric /// Decompose the machine operand's target flags into two values - the direct 327*0b57cec5SDimitry Andric /// target flag value and any of bit flags that are applied. 328*0b57cec5SDimitry Andric std::pair<unsigned, unsigned> 329*0b57cec5SDimitry Andric decomposeMachineOperandsTargetFlags(unsigned TF) const override; 330*0b57cec5SDimitry Andric 331*0b57cec5SDimitry Andric /// Return an array that contains the direct target flag values and their 332*0b57cec5SDimitry Andric /// names. 333*0b57cec5SDimitry Andric /// 334*0b57cec5SDimitry Andric /// MIR Serialization is able to serialize only the target flags that are 335*0b57cec5SDimitry Andric /// defined by this method. 336*0b57cec5SDimitry Andric ArrayRef<std::pair<unsigned, const char *>> 337*0b57cec5SDimitry Andric getSerializableDirectMachineOperandTargetFlags() const override; 338*0b57cec5SDimitry Andric 339*0b57cec5SDimitry Andric /// Return an array that contains the bitmask target flag values and their 340*0b57cec5SDimitry Andric /// names. 341*0b57cec5SDimitry Andric /// 342*0b57cec5SDimitry Andric /// MIR Serialization is able to serialize only the target flags that are 343*0b57cec5SDimitry Andric /// defined by this method. 344*0b57cec5SDimitry Andric ArrayRef<std::pair<unsigned, const char *>> 345*0b57cec5SDimitry Andric getSerializableBitmaskMachineOperandTargetFlags() const override; 346*0b57cec5SDimitry Andric 347*0b57cec5SDimitry Andric bool isTailCall(const MachineInstr &MI) const override; 348*0b57cec5SDimitry Andric 349*0b57cec5SDimitry Andric /// HexagonInstrInfo specifics. 350*0b57cec5SDimitry Andric 351*0b57cec5SDimitry Andric unsigned createVR(MachineFunction *MF, MVT VT) const; 352*0b57cec5SDimitry Andric MachineInstr *findLoopInstr(MachineBasicBlock *BB, unsigned EndLoopOp, 353*0b57cec5SDimitry Andric MachineBasicBlock *TargetBB, 354*0b57cec5SDimitry Andric SmallPtrSet<MachineBasicBlock *, 8> &Visited) const; 355*0b57cec5SDimitry Andric 356*0b57cec5SDimitry Andric bool isBaseImmOffset(const MachineInstr &MI) const; 357*0b57cec5SDimitry Andric bool isAbsoluteSet(const MachineInstr &MI) const; 358*0b57cec5SDimitry Andric bool isAccumulator(const MachineInstr &MI) const; 359*0b57cec5SDimitry Andric bool isAddrModeWithOffset(const MachineInstr &MI) const; 360*0b57cec5SDimitry Andric bool isComplex(const MachineInstr &MI) const; 361*0b57cec5SDimitry Andric bool isCompoundBranchInstr(const MachineInstr &MI) const; 362*0b57cec5SDimitry Andric bool isConstExtended(const MachineInstr &MI) const; 363*0b57cec5SDimitry Andric bool isDeallocRet(const MachineInstr &MI) const; 364*0b57cec5SDimitry Andric bool isDependent(const MachineInstr &ProdMI, 365*0b57cec5SDimitry Andric const MachineInstr &ConsMI) const; 366*0b57cec5SDimitry Andric bool isDotCurInst(const MachineInstr &MI) const; 367*0b57cec5SDimitry Andric bool isDotNewInst(const MachineInstr &MI) const; 368*0b57cec5SDimitry Andric bool isDuplexPair(const MachineInstr &MIa, const MachineInstr &MIb) const; 369*0b57cec5SDimitry Andric bool isEarlySourceInstr(const MachineInstr &MI) const; 370*0b57cec5SDimitry Andric bool isEndLoopN(unsigned Opcode) const; 371*0b57cec5SDimitry Andric bool isExpr(unsigned OpType) const; 372*0b57cec5SDimitry Andric bool isExtendable(const MachineInstr &MI) const; 373*0b57cec5SDimitry Andric bool isExtended(const MachineInstr &MI) const; 374*0b57cec5SDimitry Andric bool isFloat(const MachineInstr &MI) const; 375*0b57cec5SDimitry Andric bool isHVXMemWithAIndirect(const MachineInstr &I, 376*0b57cec5SDimitry Andric const MachineInstr &J) const; 377*0b57cec5SDimitry Andric bool isIndirectCall(const MachineInstr &MI) const; 378*0b57cec5SDimitry Andric bool isIndirectL4Return(const MachineInstr &MI) const; 379*0b57cec5SDimitry Andric bool isJumpR(const MachineInstr &MI) const; 380*0b57cec5SDimitry Andric bool isJumpWithinBranchRange(const MachineInstr &MI, unsigned offset) const; 381*0b57cec5SDimitry Andric bool isLateInstrFeedsEarlyInstr(const MachineInstr &LRMI, 382*0b57cec5SDimitry Andric const MachineInstr &ESMI) const; 383*0b57cec5SDimitry Andric bool isLateResultInstr(const MachineInstr &MI) const; 384*0b57cec5SDimitry Andric bool isLateSourceInstr(const MachineInstr &MI) const; 385*0b57cec5SDimitry Andric bool isLoopN(const MachineInstr &MI) const; 386*0b57cec5SDimitry Andric bool isMemOp(const MachineInstr &MI) const; 387*0b57cec5SDimitry Andric bool isNewValue(const MachineInstr &MI) const; 388*0b57cec5SDimitry Andric bool isNewValue(unsigned Opcode) const; 389*0b57cec5SDimitry Andric bool isNewValueInst(const MachineInstr &MI) const; 390*0b57cec5SDimitry Andric bool isNewValueJump(const MachineInstr &MI) const; 391*0b57cec5SDimitry Andric bool isNewValueJump(unsigned Opcode) const; 392*0b57cec5SDimitry Andric bool isNewValueStore(const MachineInstr &MI) const; 393*0b57cec5SDimitry Andric bool isNewValueStore(unsigned Opcode) const; 394*0b57cec5SDimitry Andric bool isOperandExtended(const MachineInstr &MI, unsigned OperandNum) const; 395*0b57cec5SDimitry Andric bool isPredicatedNew(const MachineInstr &MI) const; 396*0b57cec5SDimitry Andric bool isPredicatedNew(unsigned Opcode) const; 397*0b57cec5SDimitry Andric bool isPredicatedTrue(const MachineInstr &MI) const; 398*0b57cec5SDimitry Andric bool isPredicatedTrue(unsigned Opcode) const; 399*0b57cec5SDimitry Andric bool isPredicated(unsigned Opcode) const; 400*0b57cec5SDimitry Andric bool isPredicateLate(unsigned Opcode) const; 401*0b57cec5SDimitry Andric bool isPredictedTaken(unsigned Opcode) const; 402*0b57cec5SDimitry Andric bool isSaveCalleeSavedRegsCall(const MachineInstr &MI) const; 403*0b57cec5SDimitry Andric bool isSignExtendingLoad(const MachineInstr &MI) const; 404*0b57cec5SDimitry Andric bool isSolo(const MachineInstr &MI) const; 405*0b57cec5SDimitry Andric bool isSpillPredRegOp(const MachineInstr &MI) const; 406*0b57cec5SDimitry Andric bool isTC1(const MachineInstr &MI) const; 407*0b57cec5SDimitry Andric bool isTC2(const MachineInstr &MI) const; 408*0b57cec5SDimitry Andric bool isTC2Early(const MachineInstr &MI) const; 409*0b57cec5SDimitry Andric bool isTC4x(const MachineInstr &MI) const; 410*0b57cec5SDimitry Andric bool isToBeScheduledASAP(const MachineInstr &MI1, 411*0b57cec5SDimitry Andric const MachineInstr &MI2) const; 412*0b57cec5SDimitry Andric bool isHVXVec(const MachineInstr &MI) const; 413*0b57cec5SDimitry Andric bool isValidAutoIncImm(const EVT VT, const int Offset) const; 414*0b57cec5SDimitry Andric bool isValidOffset(unsigned Opcode, int Offset, 415*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI, bool Extend = true) const; 416*0b57cec5SDimitry Andric bool isVecAcc(const MachineInstr &MI) const; 417*0b57cec5SDimitry Andric bool isVecALU(const MachineInstr &MI) const; 418*0b57cec5SDimitry Andric bool isVecUsableNextPacket(const MachineInstr &ProdMI, 419*0b57cec5SDimitry Andric const MachineInstr &ConsMI) const; 420*0b57cec5SDimitry Andric bool isZeroExtendingLoad(const MachineInstr &MI) const; 421*0b57cec5SDimitry Andric 422*0b57cec5SDimitry Andric bool addLatencyToSchedule(const MachineInstr &MI1, 423*0b57cec5SDimitry Andric const MachineInstr &MI2) const; 424*0b57cec5SDimitry Andric bool canExecuteInBundle(const MachineInstr &First, 425*0b57cec5SDimitry Andric const MachineInstr &Second) const; 426*0b57cec5SDimitry Andric bool doesNotReturn(const MachineInstr &CallMI) const; 427*0b57cec5SDimitry Andric bool hasEHLabel(const MachineBasicBlock *B) const; 428*0b57cec5SDimitry Andric bool hasNonExtEquivalent(const MachineInstr &MI) const; 429*0b57cec5SDimitry Andric bool hasPseudoInstrPair(const MachineInstr &MI) const; 430*0b57cec5SDimitry Andric bool hasUncondBranch(const MachineBasicBlock *B) const; 431*0b57cec5SDimitry Andric bool mayBeCurLoad(const MachineInstr &MI) const; 432*0b57cec5SDimitry Andric bool mayBeNewStore(const MachineInstr &MI) const; 433*0b57cec5SDimitry Andric bool producesStall(const MachineInstr &ProdMI, 434*0b57cec5SDimitry Andric const MachineInstr &ConsMI) const; 435*0b57cec5SDimitry Andric bool producesStall(const MachineInstr &MI, 436*0b57cec5SDimitry Andric MachineBasicBlock::const_instr_iterator MII) const; 437*0b57cec5SDimitry Andric bool predCanBeUsedAsDotNew(const MachineInstr &MI, unsigned PredReg) const; 438*0b57cec5SDimitry Andric bool PredOpcodeHasJMP_c(unsigned Opcode) const; 439*0b57cec5SDimitry Andric bool predOpcodeHasNot(ArrayRef<MachineOperand> Cond) const; 440*0b57cec5SDimitry Andric 441*0b57cec5SDimitry Andric unsigned getAddrMode(const MachineInstr &MI) const; 442*0b57cec5SDimitry Andric MachineOperand *getBaseAndOffset(const MachineInstr &MI, int64_t &Offset, 443*0b57cec5SDimitry Andric unsigned &AccessSize) const; 444*0b57cec5SDimitry Andric SmallVector<MachineInstr*,2> getBranchingInstrs(MachineBasicBlock& MBB) const; 445*0b57cec5SDimitry Andric unsigned getCExtOpNum(const MachineInstr &MI) const; 446*0b57cec5SDimitry Andric HexagonII::CompoundGroup 447*0b57cec5SDimitry Andric getCompoundCandidateGroup(const MachineInstr &MI) const; 448*0b57cec5SDimitry Andric unsigned getCompoundOpcode(const MachineInstr &GA, 449*0b57cec5SDimitry Andric const MachineInstr &GB) const; 450*0b57cec5SDimitry Andric int getCondOpcode(int Opc, bool sense) const; 451*0b57cec5SDimitry Andric int getDotCurOp(const MachineInstr &MI) const; 452*0b57cec5SDimitry Andric int getNonDotCurOp(const MachineInstr &MI) const; 453*0b57cec5SDimitry Andric int getDotNewOp(const MachineInstr &MI) const; 454*0b57cec5SDimitry Andric int getDotNewPredJumpOp(const MachineInstr &MI, 455*0b57cec5SDimitry Andric const MachineBranchProbabilityInfo *MBPI) const; 456*0b57cec5SDimitry Andric int getDotNewPredOp(const MachineInstr &MI, 457*0b57cec5SDimitry Andric const MachineBranchProbabilityInfo *MBPI) const; 458*0b57cec5SDimitry Andric int getDotOldOp(const MachineInstr &MI) const; 459*0b57cec5SDimitry Andric HexagonII::SubInstructionGroup getDuplexCandidateGroup(const MachineInstr &MI) 460*0b57cec5SDimitry Andric const; 461*0b57cec5SDimitry Andric short getEquivalentHWInstr(const MachineInstr &MI) const; 462*0b57cec5SDimitry Andric unsigned getInstrTimingClassLatency(const InstrItineraryData *ItinData, 463*0b57cec5SDimitry Andric const MachineInstr &MI) const; 464*0b57cec5SDimitry Andric bool getInvertedPredSense(SmallVectorImpl<MachineOperand> &Cond) const; 465*0b57cec5SDimitry Andric unsigned getInvertedPredicatedOpcode(const int Opc) const; 466*0b57cec5SDimitry Andric int getMaxValue(const MachineInstr &MI) const; 467*0b57cec5SDimitry Andric unsigned getMemAccessSize(const MachineInstr &MI) const; 468*0b57cec5SDimitry Andric int getMinValue(const MachineInstr &MI) const; 469*0b57cec5SDimitry Andric short getNonExtOpcode(const MachineInstr &MI) const; 470*0b57cec5SDimitry Andric bool getPredReg(ArrayRef<MachineOperand> Cond, unsigned &PredReg, 471*0b57cec5SDimitry Andric unsigned &PredRegPos, unsigned &PredRegFlags) const; 472*0b57cec5SDimitry Andric short getPseudoInstrPair(const MachineInstr &MI) const; 473*0b57cec5SDimitry Andric short getRegForm(const MachineInstr &MI) const; 474*0b57cec5SDimitry Andric unsigned getSize(const MachineInstr &MI) const; 475*0b57cec5SDimitry Andric uint64_t getType(const MachineInstr &MI) const; 476*0b57cec5SDimitry Andric unsigned getUnits(const MachineInstr &MI) const; 477*0b57cec5SDimitry Andric 478*0b57cec5SDimitry Andric MachineBasicBlock::instr_iterator expandVGatherPseudo(MachineInstr &MI) const; 479*0b57cec5SDimitry Andric 480*0b57cec5SDimitry Andric /// getInstrTimingClassLatency - Compute the instruction latency of a given 481*0b57cec5SDimitry Andric /// instruction using Timing Class information, if available. 482*0b57cec5SDimitry Andric unsigned nonDbgBBSize(const MachineBasicBlock *BB) const; 483*0b57cec5SDimitry Andric unsigned nonDbgBundleSize(MachineBasicBlock::const_iterator BundleHead) const; 484*0b57cec5SDimitry Andric 485*0b57cec5SDimitry Andric void immediateExtend(MachineInstr &MI) const; 486*0b57cec5SDimitry Andric bool invertAndChangeJumpTarget(MachineInstr &MI, 487*0b57cec5SDimitry Andric MachineBasicBlock *NewTarget) const; 488*0b57cec5SDimitry Andric void genAllInsnTimingClasses(MachineFunction &MF) const; 489*0b57cec5SDimitry Andric bool reversePredSense(MachineInstr &MI) const; 490*0b57cec5SDimitry Andric unsigned reversePrediction(unsigned Opcode) const; 491*0b57cec5SDimitry Andric bool validateBranchCond(const ArrayRef<MachineOperand> &Cond) const; 492*0b57cec5SDimitry Andric 493*0b57cec5SDimitry Andric void setBundleNoShuf(MachineBasicBlock::instr_iterator MIB) const; 494*0b57cec5SDimitry Andric bool getBundleNoShuf(const MachineInstr &MIB) const; 495*0b57cec5SDimitry Andric // Addressing mode relations. 496*0b57cec5SDimitry Andric short changeAddrMode_abs_io(short Opc) const; 497*0b57cec5SDimitry Andric short changeAddrMode_io_abs(short Opc) const; 498*0b57cec5SDimitry Andric short changeAddrMode_io_pi(short Opc) const; 499*0b57cec5SDimitry Andric short changeAddrMode_io_rr(short Opc) const; 500*0b57cec5SDimitry Andric short changeAddrMode_pi_io(short Opc) const; 501*0b57cec5SDimitry Andric short changeAddrMode_rr_io(short Opc) const; 502*0b57cec5SDimitry Andric short changeAddrMode_rr_ur(short Opc) const; 503*0b57cec5SDimitry Andric short changeAddrMode_ur_rr(short Opc) const; 504*0b57cec5SDimitry Andric 505*0b57cec5SDimitry Andric short changeAddrMode_abs_io(const MachineInstr &MI) const { 506*0b57cec5SDimitry Andric return changeAddrMode_abs_io(MI.getOpcode()); 507*0b57cec5SDimitry Andric } 508*0b57cec5SDimitry Andric short changeAddrMode_io_abs(const MachineInstr &MI) const { 509*0b57cec5SDimitry Andric return changeAddrMode_io_abs(MI.getOpcode()); 510*0b57cec5SDimitry Andric } 511*0b57cec5SDimitry Andric short changeAddrMode_io_rr(const MachineInstr &MI) const { 512*0b57cec5SDimitry Andric return changeAddrMode_io_rr(MI.getOpcode()); 513*0b57cec5SDimitry Andric } 514*0b57cec5SDimitry Andric short changeAddrMode_rr_io(const MachineInstr &MI) const { 515*0b57cec5SDimitry Andric return changeAddrMode_rr_io(MI.getOpcode()); 516*0b57cec5SDimitry Andric } 517*0b57cec5SDimitry Andric short changeAddrMode_rr_ur(const MachineInstr &MI) const { 518*0b57cec5SDimitry Andric return changeAddrMode_rr_ur(MI.getOpcode()); 519*0b57cec5SDimitry Andric } 520*0b57cec5SDimitry Andric short changeAddrMode_ur_rr(const MachineInstr &MI) const { 521*0b57cec5SDimitry Andric return changeAddrMode_ur_rr(MI.getOpcode()); 522*0b57cec5SDimitry Andric } 523*0b57cec5SDimitry Andric }; 524*0b57cec5SDimitry Andric 525*0b57cec5SDimitry Andric } // end namespace llvm 526*0b57cec5SDimitry Andric 527*0b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONINSTRINFO_H 528