10b57cec5SDimitry Andric //===- HexagonInstrInfo.h - Hexagon 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 // 90b57cec5SDimitry Andric // This file contains the Hexagon implementation of the TargetInstrInfo class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONINSTRINFO_H 140b57cec5SDimitry Andric #define LLVM_LIB_TARGET_HEXAGON_HEXAGONINSTRINFO_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "MCTargetDesc/HexagonBaseInfo.h" 170b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 180b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 200b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 210b57cec5SDimitry Andric #include "llvm/CodeGen/ValueTypes.h" 22*0fca6ea1SDimitry Andric #include "llvm/CodeGenTypes/MachineValueType.h" 230b57cec5SDimitry Andric #include <cstdint> 240b57cec5SDimitry Andric #include <vector> 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric #define GET_INSTRINFO_HEADER 270b57cec5SDimitry Andric #include "HexagonGenInstrInfo.inc" 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric namespace llvm { 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric class HexagonSubtarget; 320b57cec5SDimitry Andric class MachineBranchProbabilityInfo; 330b57cec5SDimitry Andric class MachineFunction; 340b57cec5SDimitry Andric class MachineInstr; 350b57cec5SDimitry Andric class MachineOperand; 360b57cec5SDimitry Andric class TargetRegisterInfo; 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric class HexagonInstrInfo : public HexagonGenInstrInfo { 390b57cec5SDimitry Andric const HexagonSubtarget &Subtarget; 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric enum BundleAttribute { 420b57cec5SDimitry Andric memShufDisabledMask = 0x4 430b57cec5SDimitry Andric }; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric virtual void anchor(); 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric public: 480b57cec5SDimitry Andric explicit HexagonInstrInfo(HexagonSubtarget &ST); 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric /// TargetInstrInfo overrides. 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric /// If the specified machine instruction is a direct 530b57cec5SDimitry Andric /// load from a stack slot, return the virtual or physical register number of 540b57cec5SDimitry Andric /// the destination along with the FrameIndex of the loaded stack slot. If 550b57cec5SDimitry Andric /// not, return 0. This predicate must return 0 if the instruction has 560b57cec5SDimitry Andric /// any side effects other than loading from the stack slot. 57*0fca6ea1SDimitry Andric Register isLoadFromStackSlot(const MachineInstr &MI, 580b57cec5SDimitry Andric int &FrameIndex) const override; 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric /// If the specified machine instruction is a direct 610b57cec5SDimitry Andric /// store to a stack slot, return the virtual or physical register number of 620b57cec5SDimitry Andric /// the source reg along with the FrameIndex of the loaded stack slot. If 630b57cec5SDimitry Andric /// not, return 0. This predicate must return 0 if the instruction has 640b57cec5SDimitry Andric /// any side effects other than storing to the stack slot. 65*0fca6ea1SDimitry Andric Register isStoreToStackSlot(const MachineInstr &MI, 660b57cec5SDimitry Andric int &FrameIndex) const override; 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric /// Check if the instruction or the bundle of instructions has 690b57cec5SDimitry Andric /// load from stack slots. Return the frameindex and machine memory operand 700b57cec5SDimitry Andric /// if true. 710b57cec5SDimitry Andric bool hasLoadFromStackSlot( 720b57cec5SDimitry Andric const MachineInstr &MI, 730b57cec5SDimitry Andric SmallVectorImpl<const MachineMemOperand *> &Accesses) const override; 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric /// Check if the instruction or the bundle of instructions has 760b57cec5SDimitry Andric /// store to stack slots. Return the frameindex and machine memory operand 770b57cec5SDimitry Andric /// if true. 780b57cec5SDimitry Andric bool hasStoreToStackSlot( 790b57cec5SDimitry Andric const MachineInstr &MI, 800b57cec5SDimitry Andric SmallVectorImpl<const MachineMemOperand *> &Accesses) const override; 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric /// Analyze the branching code at the end of MBB, returning 830b57cec5SDimitry Andric /// true if it cannot be understood (e.g. it's a switch dispatch or isn't 840b57cec5SDimitry Andric /// implemented for a target). Upon success, this returns false and returns 850b57cec5SDimitry Andric /// with the following information in various cases: 860b57cec5SDimitry Andric /// 870b57cec5SDimitry Andric /// 1. If this block ends with no branches (it just falls through to its succ) 880b57cec5SDimitry Andric /// just return false, leaving TBB/FBB null. 890b57cec5SDimitry Andric /// 2. If this block ends with only an unconditional branch, it sets TBB to be 900b57cec5SDimitry Andric /// the destination block. 910b57cec5SDimitry Andric /// 3. If this block ends with a conditional branch and it falls through to a 920b57cec5SDimitry Andric /// successor block, it sets TBB to be the branch destination block and a 930b57cec5SDimitry Andric /// list of operands that evaluate the condition. These operands can be 940b57cec5SDimitry Andric /// passed to other TargetInstrInfo methods to create new branches. 950b57cec5SDimitry Andric /// 4. If this block ends with a conditional branch followed by an 960b57cec5SDimitry Andric /// unconditional branch, it returns the 'true' destination in TBB, the 970b57cec5SDimitry Andric /// 'false' destination in FBB, and a list of operands that evaluate the 980b57cec5SDimitry Andric /// condition. These operands can be passed to other TargetInstrInfo 990b57cec5SDimitry Andric /// methods to create new branches. 1000b57cec5SDimitry Andric /// 1010b57cec5SDimitry Andric /// Note that removeBranch and insertBranch must be implemented to support 1020b57cec5SDimitry Andric /// cases where this method returns success. 1030b57cec5SDimitry Andric /// 1040b57cec5SDimitry Andric /// If AllowModify is true, then this routine is allowed to modify the basic 1050b57cec5SDimitry Andric /// block (e.g. delete instructions after the unconditional branch). 1060b57cec5SDimitry Andric bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 1070b57cec5SDimitry Andric MachineBasicBlock *&FBB, 1080b57cec5SDimitry Andric SmallVectorImpl<MachineOperand> &Cond, 1090b57cec5SDimitry Andric bool AllowModify) const override; 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric /// Remove the branching code at the end of the specific MBB. 1125ffd83dbSDimitry Andric /// This is only invoked in cases where analyzeBranch returns success. It 1130b57cec5SDimitry Andric /// returns the number of instructions that were removed. 1140b57cec5SDimitry Andric unsigned removeBranch(MachineBasicBlock &MBB, 1150b57cec5SDimitry Andric int *BytesRemoved = nullptr) const override; 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric /// Insert branch code into the end of the specified MachineBasicBlock. 1180b57cec5SDimitry Andric /// The operands to this method are the same as those 1195ffd83dbSDimitry Andric /// returned by analyzeBranch. This is only invoked in cases where 1205ffd83dbSDimitry Andric /// analyzeBranch returns success. It returns the number of instructions 1210b57cec5SDimitry Andric /// inserted. 1220b57cec5SDimitry Andric /// 1230b57cec5SDimitry Andric /// It is also invoked by tail merging to add unconditional branches in 1245ffd83dbSDimitry Andric /// cases where analyzeBranch doesn't apply because there was no original 1250b57cec5SDimitry Andric /// branch to analyze. At least this much must be implemented, else tail 1260b57cec5SDimitry Andric /// merging needs to be disabled. 1270b57cec5SDimitry Andric unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 1280b57cec5SDimitry Andric MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, 1290b57cec5SDimitry Andric const DebugLoc &DL, 1300b57cec5SDimitry Andric int *BytesAdded = nullptr) const override; 1310b57cec5SDimitry Andric 1328bcb0991SDimitry Andric /// Analyze loop L, which must be a single-basic-block loop, and if the 1338bcb0991SDimitry Andric /// conditions can be understood enough produce a PipelinerLoopInfo object. 1348bcb0991SDimitry Andric std::unique_ptr<PipelinerLoopInfo> 1358bcb0991SDimitry Andric analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override; 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric /// Return true if it's profitable to predicate 1380b57cec5SDimitry Andric /// instructions with accumulated instruction latency of "NumCycles" 1390b57cec5SDimitry Andric /// of the specified basic block, where the probability of the instructions 1400b57cec5SDimitry Andric /// being executed is given by Probability, and Confidence is a measure 1410b57cec5SDimitry Andric /// of our confidence that it will be properly predicted. 1420b57cec5SDimitry Andric bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, 1430b57cec5SDimitry Andric unsigned ExtraPredCycles, 1440b57cec5SDimitry Andric BranchProbability Probability) const override; 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric /// Second variant of isProfitableToIfCvt. This one 1470b57cec5SDimitry Andric /// checks for the case where two basic blocks from true and false path 1480b57cec5SDimitry Andric /// of a if-then-else (diamond) are predicated on mutally exclusive 1490b57cec5SDimitry Andric /// predicates, where the probability of the true path being taken is given 1500b57cec5SDimitry Andric /// by Probability, and Confidence is a measure of our confidence that it 1510b57cec5SDimitry Andric /// will be properly predicted. 1520b57cec5SDimitry Andric bool isProfitableToIfCvt(MachineBasicBlock &TMBB, 1530b57cec5SDimitry Andric unsigned NumTCycles, unsigned ExtraTCycles, 1540b57cec5SDimitry Andric MachineBasicBlock &FMBB, 1550b57cec5SDimitry Andric unsigned NumFCycles, unsigned ExtraFCycles, 1560b57cec5SDimitry Andric BranchProbability Probability) const override; 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric /// Return true if it's profitable for if-converter to duplicate instructions 1590b57cec5SDimitry Andric /// of specified accumulated instruction latencies in the specified MBB to 1600b57cec5SDimitry Andric /// enable if-conversion. 1610b57cec5SDimitry Andric /// The probability of the instructions being executed is given by 1620b57cec5SDimitry Andric /// Probability, and Confidence is a measure of our confidence that it 1630b57cec5SDimitry Andric /// will be properly predicted. 1640b57cec5SDimitry Andric bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, 1650b57cec5SDimitry Andric BranchProbability Probability) const override; 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric /// Emit instructions to copy a pair of physical registers. 1680b57cec5SDimitry Andric /// 1690b57cec5SDimitry Andric /// This function should support copies within any legal register class as 1700b57cec5SDimitry Andric /// well as any cross-class copies created during instruction selection. 1710b57cec5SDimitry Andric /// 1720b57cec5SDimitry Andric /// The source and destination registers may overlap, which may require a 1730b57cec5SDimitry Andric /// careful implementation when multiple copy instructions are required for 1740b57cec5SDimitry Andric /// large registers. See for example the ARM target. 1750b57cec5SDimitry Andric void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 176480093f4SDimitry Andric const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, 1770b57cec5SDimitry Andric bool KillSrc) const override; 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric /// Store the specified register of the given register class to the specified 1800b57cec5SDimitry Andric /// stack frame index. The store instruction is to be added to the given 1810b57cec5SDimitry Andric /// machine basic block before the specified machine instruction. If isKill 1820b57cec5SDimitry Andric /// is true, the register operand is the last use and must be marked kill. 1830b57cec5SDimitry Andric void storeRegToStackSlot(MachineBasicBlock &MBB, 184bdd1243dSDimitry Andric MachineBasicBlock::iterator MBBI, Register SrcReg, 185bdd1243dSDimitry Andric bool isKill, int FrameIndex, 1860b57cec5SDimitry Andric const TargetRegisterClass *RC, 187bdd1243dSDimitry Andric const TargetRegisterInfo *TRI, 188bdd1243dSDimitry Andric Register VReg) const override; 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric /// Load the specified register of the given register class from the specified 1910b57cec5SDimitry Andric /// stack frame index. The load instruction is to be added to the given 1920b57cec5SDimitry Andric /// machine basic block before the specified machine instruction. 1930b57cec5SDimitry Andric void loadRegFromStackSlot(MachineBasicBlock &MBB, 194bdd1243dSDimitry Andric MachineBasicBlock::iterator MBBI, Register DestReg, 195bdd1243dSDimitry Andric int FrameIndex, const TargetRegisterClass *RC, 196bdd1243dSDimitry Andric const TargetRegisterInfo *TRI, 197bdd1243dSDimitry Andric Register VReg) const override; 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric /// This function is called for all pseudo instructions 2000b57cec5SDimitry Andric /// that remain after register allocation. Many pseudo instructions are 2010b57cec5SDimitry Andric /// created to help register allocation. This is the place to convert them 2020b57cec5SDimitry Andric /// into real instructions. The target can edit MI in place, or it can insert 2030b57cec5SDimitry Andric /// new instructions and erase MI. The function should return true if 2040b57cec5SDimitry Andric /// anything was changed. 2050b57cec5SDimitry Andric bool expandPostRAPseudo(MachineInstr &MI) const override; 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric /// Get the base register and byte offset of a load/store instr. 2085ffd83dbSDimitry Andric bool getMemOperandsWithOffsetWidth( 2095ffd83dbSDimitry Andric const MachineInstr &LdSt, 2105ffd83dbSDimitry Andric SmallVectorImpl<const MachineOperand *> &BaseOps, int64_t &Offset, 211*0fca6ea1SDimitry Andric bool &OffsetIsScalable, LocationSize &Width, 2120b57cec5SDimitry Andric const TargetRegisterInfo *TRI) const override; 2130b57cec5SDimitry Andric 2140b57cec5SDimitry Andric /// Reverses the branch condition of the specified condition list, 2150b57cec5SDimitry Andric /// returning false on success and true if it cannot be reversed. 2160b57cec5SDimitry Andric bool reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) 2170b57cec5SDimitry Andric const override; 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric /// Insert a noop into the instruction stream at the specified point. 2200b57cec5SDimitry Andric void insertNoop(MachineBasicBlock &MBB, 2210b57cec5SDimitry Andric MachineBasicBlock::iterator MI) const override; 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric /// Returns true if the instruction is already predicated. 2240b57cec5SDimitry Andric bool isPredicated(const MachineInstr &MI) const override; 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric /// Return true for post-incremented instructions. 2270b57cec5SDimitry Andric bool isPostIncrement(const MachineInstr &MI) const override; 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric /// Convert the instruction into a predicated instruction. 2300b57cec5SDimitry Andric /// It returns true if the operation was successful. 2310b57cec5SDimitry Andric bool PredicateInstruction(MachineInstr &MI, 2320b57cec5SDimitry Andric ArrayRef<MachineOperand> Cond) const override; 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric /// Returns true if the first specified predicate 2350b57cec5SDimitry Andric /// subsumes the second, e.g. GE subsumes GT. 2360b57cec5SDimitry Andric bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1, 2370b57cec5SDimitry Andric ArrayRef<MachineOperand> Pred2) const override; 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric /// If the specified instruction defines any predicate 2400b57cec5SDimitry Andric /// or condition code register(s) used for predication, returns true as well 2410b57cec5SDimitry Andric /// as the definition predicate(s) by reference. 242e8d8bef9SDimitry Andric bool ClobbersPredicate(MachineInstr &MI, std::vector<MachineOperand> &Pred, 243e8d8bef9SDimitry Andric bool SkipDead) const override; 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric /// Return true if the specified instruction can be predicated. 2460b57cec5SDimitry Andric /// By default, this returns true for every instruction with a 2470b57cec5SDimitry Andric /// PredicateOperand. 2480b57cec5SDimitry Andric bool isPredicable(const MachineInstr &MI) const override; 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andric /// Test if the given instruction should be considered a scheduling boundary. 2510b57cec5SDimitry Andric /// This primarily includes labels and terminators. 2520b57cec5SDimitry Andric bool isSchedulingBoundary(const MachineInstr &MI, 2530b57cec5SDimitry Andric const MachineBasicBlock *MBB, 2540b57cec5SDimitry Andric const MachineFunction &MF) const override; 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric /// Measure the specified inline asm to determine an approximation of its 2570b57cec5SDimitry Andric /// length. 2580b57cec5SDimitry Andric unsigned getInlineAsmLength( 2590b57cec5SDimitry Andric const char *Str, 2600b57cec5SDimitry Andric const MCAsmInfo &MAI, 2610b57cec5SDimitry Andric const TargetSubtargetInfo *STI = nullptr) const override; 2620b57cec5SDimitry Andric 2630b57cec5SDimitry Andric /// Allocate and return a hazard recognizer to use for this target when 2640b57cec5SDimitry Andric /// scheduling the machine instructions after register allocation. 2650b57cec5SDimitry Andric ScheduleHazardRecognizer* 2660b57cec5SDimitry Andric CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, 2670b57cec5SDimitry Andric const ScheduleDAG *DAG) const override; 2680b57cec5SDimitry Andric 2690b57cec5SDimitry Andric /// For a comparison instruction, return the source registers 2700b57cec5SDimitry Andric /// in SrcReg and SrcReg2 if having two register operands, and the value it 2710b57cec5SDimitry Andric /// compares against in CmpValue. Return true if the comparison instruction 2720b57cec5SDimitry Andric /// can be analyzed. 2735ffd83dbSDimitry Andric bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, 274349cc55cSDimitry Andric Register &SrcReg2, int64_t &Mask, 275349cc55cSDimitry Andric int64_t &Value) const override; 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric /// Compute the instruction latency of a given instruction. 2780b57cec5SDimitry Andric /// If the instruction has higher cost when predicated, it's returned via 2790b57cec5SDimitry Andric /// PredCost. 2800b57cec5SDimitry Andric unsigned getInstrLatency(const InstrItineraryData *ItinData, 2810b57cec5SDimitry Andric const MachineInstr &MI, 2820b57cec5SDimitry Andric unsigned *PredCost = nullptr) const override; 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric /// Create machine specific model for scheduling. 2850b57cec5SDimitry Andric DFAPacketizer * 2860b57cec5SDimitry Andric CreateTargetScheduleState(const TargetSubtargetInfo &STI) const override; 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric // Sometimes, it is possible for the target 2890b57cec5SDimitry Andric // to tell, even without aliasing information, that two MIs access different 2900b57cec5SDimitry Andric // memory addresses. This function returns true if two MIs access different 2910b57cec5SDimitry Andric // memory addresses and false otherwise. 2920b57cec5SDimitry Andric bool 2930b57cec5SDimitry Andric areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, 2948bcb0991SDimitry Andric const MachineInstr &MIb) const override; 2950b57cec5SDimitry Andric 2960b57cec5SDimitry Andric /// For instructions with a base and offset, return the position of the 2970b57cec5SDimitry Andric /// base register and offset operands. 2980b57cec5SDimitry Andric bool getBaseAndOffsetPosition(const MachineInstr &MI, unsigned &BasePos, 2990b57cec5SDimitry Andric unsigned &OffsetPos) const override; 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric /// If the instruction is an increment of a constant value, return the amount. 3020b57cec5SDimitry Andric bool getIncrementValue(const MachineInstr &MI, int &Value) const override; 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric /// getOperandLatency - Compute and return the use operand latency of a given 3050b57cec5SDimitry Andric /// pair of def and use. 3060b57cec5SDimitry Andric /// In most cases, the static scheduling itinerary was enough to determine the 3070b57cec5SDimitry Andric /// operand latency. But it may not be possible for instructions with variable 3080b57cec5SDimitry Andric /// number of defs / uses. 3090b57cec5SDimitry Andric /// 3100b57cec5SDimitry Andric /// This is a raw interface to the itinerary that may be directly overriden by 3110b57cec5SDimitry Andric /// a target. Use computeOperandLatency to get the best estimate of latency. 3125f757f3fSDimitry Andric std::optional<unsigned> getOperandLatency(const InstrItineraryData *ItinData, 3135f757f3fSDimitry Andric const MachineInstr &DefMI, 3145f757f3fSDimitry Andric unsigned DefIdx, 3150b57cec5SDimitry Andric const MachineInstr &UseMI, 3160b57cec5SDimitry Andric unsigned UseIdx) const override; 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric /// Decompose the machine operand's target flags into two values - the direct 3190b57cec5SDimitry Andric /// target flag value and any of bit flags that are applied. 3200b57cec5SDimitry Andric std::pair<unsigned, unsigned> 3210b57cec5SDimitry Andric decomposeMachineOperandsTargetFlags(unsigned TF) const override; 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric /// Return an array that contains the direct target flag values and their 3240b57cec5SDimitry Andric /// names. 3250b57cec5SDimitry Andric /// 3260b57cec5SDimitry Andric /// MIR Serialization is able to serialize only the target flags that are 3270b57cec5SDimitry Andric /// defined by this method. 3280b57cec5SDimitry Andric ArrayRef<std::pair<unsigned, const char *>> 3290b57cec5SDimitry Andric getSerializableDirectMachineOperandTargetFlags() const override; 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric /// Return an array that contains the bitmask target flag values and their 3320b57cec5SDimitry Andric /// names. 3330b57cec5SDimitry Andric /// 3340b57cec5SDimitry Andric /// MIR Serialization is able to serialize only the target flags that are 3350b57cec5SDimitry Andric /// defined by this method. 3360b57cec5SDimitry Andric ArrayRef<std::pair<unsigned, const char *>> 3370b57cec5SDimitry Andric getSerializableBitmaskMachineOperandTargetFlags() const override; 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric bool isTailCall(const MachineInstr &MI) const override; 34004eeddc0SDimitry Andric bool isAsCheapAsAMove(const MachineInstr &MI) const override; 34104eeddc0SDimitry Andric 34204eeddc0SDimitry Andric // Return true if the instruction should be sunk by MachineSink. 34304eeddc0SDimitry Andric // MachineSink determines on its own whether the instruction is safe to sink; 34404eeddc0SDimitry Andric // this gives the target a hook to override the default behavior with regards 34504eeddc0SDimitry Andric // to which instructions should be sunk. 34604eeddc0SDimitry Andric bool shouldSink(const MachineInstr &MI) const override; 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric /// HexagonInstrInfo specifics. 3490b57cec5SDimitry Andric 350bdd1243dSDimitry Andric Register createVR(MachineFunction *MF, MVT VT) const; 3510b57cec5SDimitry Andric MachineInstr *findLoopInstr(MachineBasicBlock *BB, unsigned EndLoopOp, 3520b57cec5SDimitry Andric MachineBasicBlock *TargetBB, 3530b57cec5SDimitry Andric SmallPtrSet<MachineBasicBlock *, 8> &Visited) const; 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric bool isAbsoluteSet(const MachineInstr &MI) const; 3560b57cec5SDimitry Andric bool isAccumulator(const MachineInstr &MI) const; 3570b57cec5SDimitry Andric bool isAddrModeWithOffset(const MachineInstr &MI) const; 3585ffd83dbSDimitry Andric bool isBaseImmOffset(const MachineInstr &MI) const; 3590b57cec5SDimitry Andric bool isComplex(const MachineInstr &MI) const; 3600b57cec5SDimitry Andric bool isCompoundBranchInstr(const MachineInstr &MI) const; 3610b57cec5SDimitry Andric bool isConstExtended(const MachineInstr &MI) const; 3620b57cec5SDimitry Andric bool isDeallocRet(const MachineInstr &MI) const; 3630b57cec5SDimitry Andric bool isDependent(const MachineInstr &ProdMI, 3640b57cec5SDimitry Andric const MachineInstr &ConsMI) const; 3650b57cec5SDimitry Andric bool isDotCurInst(const MachineInstr &MI) const; 3660b57cec5SDimitry Andric bool isDotNewInst(const MachineInstr &MI) const; 3670b57cec5SDimitry Andric bool isDuplexPair(const MachineInstr &MIa, const MachineInstr &MIb) const; 3680b57cec5SDimitry Andric bool isEndLoopN(unsigned Opcode) const; 3690b57cec5SDimitry Andric bool isExpr(unsigned OpType) const; 3700b57cec5SDimitry Andric bool isExtendable(const MachineInstr &MI) const; 3710b57cec5SDimitry Andric bool isExtended(const MachineInstr &MI) const; 3720b57cec5SDimitry Andric bool isFloat(const MachineInstr &MI) const; 3730b57cec5SDimitry Andric bool isHVXMemWithAIndirect(const MachineInstr &I, 3740b57cec5SDimitry Andric const MachineInstr &J) const; 3750b57cec5SDimitry Andric bool isIndirectCall(const MachineInstr &MI) const; 3760b57cec5SDimitry Andric bool isIndirectL4Return(const MachineInstr &MI) const; 3770b57cec5SDimitry Andric bool isJumpR(const MachineInstr &MI) const; 3780b57cec5SDimitry Andric bool isJumpWithinBranchRange(const MachineInstr &MI, unsigned offset) const; 3790b57cec5SDimitry Andric bool isLateSourceInstr(const MachineInstr &MI) const; 3800b57cec5SDimitry Andric bool isLoopN(const MachineInstr &MI) const; 3810b57cec5SDimitry Andric bool isMemOp(const MachineInstr &MI) const; 3820b57cec5SDimitry Andric bool isNewValue(const MachineInstr &MI) const; 3830b57cec5SDimitry Andric bool isNewValue(unsigned Opcode) const; 3840b57cec5SDimitry Andric bool isNewValueInst(const MachineInstr &MI) const; 3850b57cec5SDimitry Andric bool isNewValueJump(const MachineInstr &MI) const; 3860b57cec5SDimitry Andric bool isNewValueJump(unsigned Opcode) const; 3870b57cec5SDimitry Andric bool isNewValueStore(const MachineInstr &MI) const; 3880b57cec5SDimitry Andric bool isNewValueStore(unsigned Opcode) const; 3890b57cec5SDimitry Andric bool isOperandExtended(const MachineInstr &MI, unsigned OperandNum) const; 3900b57cec5SDimitry Andric bool isPredicatedNew(const MachineInstr &MI) const; 3910b57cec5SDimitry Andric bool isPredicatedNew(unsigned Opcode) const; 3920b57cec5SDimitry Andric bool isPredicatedTrue(const MachineInstr &MI) const; 3930b57cec5SDimitry Andric bool isPredicatedTrue(unsigned Opcode) const; 3940b57cec5SDimitry Andric bool isPredicated(unsigned Opcode) const; 3950b57cec5SDimitry Andric bool isPredicateLate(unsigned Opcode) const; 3960b57cec5SDimitry Andric bool isPredictedTaken(unsigned Opcode) const; 3975ffd83dbSDimitry Andric bool isPureSlot0(const MachineInstr &MI) const; 3985ffd83dbSDimitry Andric bool isRestrictNoSlot1Store(const MachineInstr &MI) const; 3990b57cec5SDimitry Andric bool isSaveCalleeSavedRegsCall(const MachineInstr &MI) const; 4000b57cec5SDimitry Andric bool isSignExtendingLoad(const MachineInstr &MI) const; 4010b57cec5SDimitry Andric bool isSolo(const MachineInstr &MI) const; 4020b57cec5SDimitry Andric bool isSpillPredRegOp(const MachineInstr &MI) const; 4030b57cec5SDimitry Andric bool isTC1(const MachineInstr &MI) const; 4040b57cec5SDimitry Andric bool isTC2(const MachineInstr &MI) const; 4050b57cec5SDimitry Andric bool isTC2Early(const MachineInstr &MI) const; 4060b57cec5SDimitry Andric bool isTC4x(const MachineInstr &MI) const; 4070b57cec5SDimitry Andric bool isToBeScheduledASAP(const MachineInstr &MI1, 4080b57cec5SDimitry Andric const MachineInstr &MI2) const; 4090b57cec5SDimitry Andric bool isHVXVec(const MachineInstr &MI) const; 4100b57cec5SDimitry Andric bool isValidAutoIncImm(const EVT VT, const int Offset) const; 4110b57cec5SDimitry Andric bool isValidOffset(unsigned Opcode, int Offset, 4120b57cec5SDimitry Andric const TargetRegisterInfo *TRI, bool Extend = true) const; 4130b57cec5SDimitry Andric bool isVecAcc(const MachineInstr &MI) const; 4140b57cec5SDimitry Andric bool isVecALU(const MachineInstr &MI) const; 4150b57cec5SDimitry Andric bool isVecUsableNextPacket(const MachineInstr &ProdMI, 4160b57cec5SDimitry Andric const MachineInstr &ConsMI) const; 4170b57cec5SDimitry Andric bool isZeroExtendingLoad(const MachineInstr &MI) const; 4180b57cec5SDimitry Andric 4190b57cec5SDimitry Andric bool addLatencyToSchedule(const MachineInstr &MI1, 4200b57cec5SDimitry Andric const MachineInstr &MI2) const; 4210b57cec5SDimitry Andric bool canExecuteInBundle(const MachineInstr &First, 4220b57cec5SDimitry Andric const MachineInstr &Second) const; 4230b57cec5SDimitry Andric bool doesNotReturn(const MachineInstr &CallMI) const; 4240b57cec5SDimitry Andric bool hasEHLabel(const MachineBasicBlock *B) const; 4250b57cec5SDimitry Andric bool hasNonExtEquivalent(const MachineInstr &MI) const; 4260b57cec5SDimitry Andric bool hasPseudoInstrPair(const MachineInstr &MI) const; 4270b57cec5SDimitry Andric bool hasUncondBranch(const MachineBasicBlock *B) const; 4280b57cec5SDimitry Andric bool mayBeCurLoad(const MachineInstr &MI) const; 4290b57cec5SDimitry Andric bool mayBeNewStore(const MachineInstr &MI) const; 4300b57cec5SDimitry Andric bool producesStall(const MachineInstr &ProdMI, 4310b57cec5SDimitry Andric const MachineInstr &ConsMI) const; 4320b57cec5SDimitry Andric bool producesStall(const MachineInstr &MI, 4330b57cec5SDimitry Andric MachineBasicBlock::const_instr_iterator MII) const; 434bdd1243dSDimitry Andric bool predCanBeUsedAsDotNew(const MachineInstr &MI, Register PredReg) const; 4350b57cec5SDimitry Andric bool PredOpcodeHasJMP_c(unsigned Opcode) const; 4360b57cec5SDimitry Andric bool predOpcodeHasNot(ArrayRef<MachineOperand> Cond) const; 4370b57cec5SDimitry Andric 4380b57cec5SDimitry Andric unsigned getAddrMode(const MachineInstr &MI) const; 4390b57cec5SDimitry Andric MachineOperand *getBaseAndOffset(const MachineInstr &MI, int64_t &Offset, 440*0fca6ea1SDimitry Andric LocationSize &AccessSize) const; 4410b57cec5SDimitry Andric SmallVector<MachineInstr*,2> getBranchingInstrs(MachineBasicBlock& MBB) const; 4420b57cec5SDimitry Andric unsigned getCExtOpNum(const MachineInstr &MI) const; 4430b57cec5SDimitry Andric HexagonII::CompoundGroup 4440b57cec5SDimitry Andric getCompoundCandidateGroup(const MachineInstr &MI) const; 4450b57cec5SDimitry Andric unsigned getCompoundOpcode(const MachineInstr &GA, 4460b57cec5SDimitry Andric const MachineInstr &GB) const; 4475ffd83dbSDimitry Andric int getDuplexOpcode(const MachineInstr &MI, bool ForBigCore = true) const; 4480b57cec5SDimitry Andric int getCondOpcode(int Opc, bool sense) const; 4490b57cec5SDimitry Andric int getDotCurOp(const MachineInstr &MI) const; 4500b57cec5SDimitry Andric int getNonDotCurOp(const MachineInstr &MI) const; 4510b57cec5SDimitry Andric int getDotNewOp(const MachineInstr &MI) const; 4520b57cec5SDimitry Andric int getDotNewPredJumpOp(const MachineInstr &MI, 4530b57cec5SDimitry Andric const MachineBranchProbabilityInfo *MBPI) const; 4540b57cec5SDimitry Andric int getDotNewPredOp(const MachineInstr &MI, 4550b57cec5SDimitry Andric const MachineBranchProbabilityInfo *MBPI) const; 4560b57cec5SDimitry Andric int getDotOldOp(const MachineInstr &MI) const; 4570b57cec5SDimitry Andric HexagonII::SubInstructionGroup getDuplexCandidateGroup(const MachineInstr &MI) 4580b57cec5SDimitry Andric const; 4590b57cec5SDimitry Andric short getEquivalentHWInstr(const MachineInstr &MI) const; 4600b57cec5SDimitry Andric unsigned getInstrTimingClassLatency(const InstrItineraryData *ItinData, 4610b57cec5SDimitry Andric const MachineInstr &MI) const; 4620b57cec5SDimitry Andric bool getInvertedPredSense(SmallVectorImpl<MachineOperand> &Cond) const; 4630b57cec5SDimitry Andric unsigned getInvertedPredicatedOpcode(const int Opc) const; 4640b57cec5SDimitry Andric int getMaxValue(const MachineInstr &MI) const; 4650b57cec5SDimitry Andric unsigned getMemAccessSize(const MachineInstr &MI) const; 4660b57cec5SDimitry Andric int getMinValue(const MachineInstr &MI) const; 4670b57cec5SDimitry Andric short getNonExtOpcode(const MachineInstr &MI) const; 468bdd1243dSDimitry Andric bool getPredReg(ArrayRef<MachineOperand> Cond, Register &PredReg, 4690b57cec5SDimitry Andric unsigned &PredRegPos, unsigned &PredRegFlags) const; 4700b57cec5SDimitry Andric short getPseudoInstrPair(const MachineInstr &MI) const; 4710b57cec5SDimitry Andric short getRegForm(const MachineInstr &MI) const; 4720b57cec5SDimitry Andric unsigned getSize(const MachineInstr &MI) const; 4730b57cec5SDimitry Andric uint64_t getType(const MachineInstr &MI) const; 4745ffd83dbSDimitry Andric InstrStage::FuncUnits getUnits(const MachineInstr &MI) const; 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric MachineBasicBlock::instr_iterator expandVGatherPseudo(MachineInstr &MI) const; 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric /// getInstrTimingClassLatency - Compute the instruction latency of a given 4790b57cec5SDimitry Andric /// instruction using Timing Class information, if available. 4800b57cec5SDimitry Andric unsigned nonDbgBBSize(const MachineBasicBlock *BB) const; 4810b57cec5SDimitry Andric unsigned nonDbgBundleSize(MachineBasicBlock::const_iterator BundleHead) const; 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric void immediateExtend(MachineInstr &MI) const; 4840b57cec5SDimitry Andric bool invertAndChangeJumpTarget(MachineInstr &MI, 4850b57cec5SDimitry Andric MachineBasicBlock *NewTarget) const; 4860b57cec5SDimitry Andric void genAllInsnTimingClasses(MachineFunction &MF) const; 4870b57cec5SDimitry Andric bool reversePredSense(MachineInstr &MI) const; 4880b57cec5SDimitry Andric unsigned reversePrediction(unsigned Opcode) const; 4890b57cec5SDimitry Andric bool validateBranchCond(const ArrayRef<MachineOperand> &Cond) const; 4900b57cec5SDimitry Andric 4910b57cec5SDimitry Andric void setBundleNoShuf(MachineBasicBlock::instr_iterator MIB) const; 4920b57cec5SDimitry Andric bool getBundleNoShuf(const MachineInstr &MIB) const; 4935ffd83dbSDimitry Andric 4945ffd83dbSDimitry Andric // When TinyCore with Duplexes is enabled, this function is used to translate 4955ffd83dbSDimitry Andric // tiny-instructions to big-instructions and vice versa to get the slot 4965ffd83dbSDimitry Andric // consumption. 4975ffd83dbSDimitry Andric void changeDuplexOpcode(MachineBasicBlock::instr_iterator MII, 4985ffd83dbSDimitry Andric bool ToBigInstrs) const; 4995ffd83dbSDimitry Andric void translateInstrsForDup(MachineFunction &MF, 5005ffd83dbSDimitry Andric bool ToBigInstrs = true) const; 5015ffd83dbSDimitry Andric void translateInstrsForDup(MachineBasicBlock::instr_iterator MII, 5025ffd83dbSDimitry Andric bool ToBigInstrs) const; 5035ffd83dbSDimitry Andric 5040b57cec5SDimitry Andric // Addressing mode relations. 5050b57cec5SDimitry Andric short changeAddrMode_abs_io(short Opc) const; 5060b57cec5SDimitry Andric short changeAddrMode_io_abs(short Opc) const; 5070b57cec5SDimitry Andric short changeAddrMode_io_pi(short Opc) const; 5080b57cec5SDimitry Andric short changeAddrMode_io_rr(short Opc) const; 5090b57cec5SDimitry Andric short changeAddrMode_pi_io(short Opc) const; 5100b57cec5SDimitry Andric short changeAddrMode_rr_io(short Opc) const; 5110b57cec5SDimitry Andric short changeAddrMode_rr_ur(short Opc) const; 5120b57cec5SDimitry Andric short changeAddrMode_ur_rr(short Opc) const; 5130b57cec5SDimitry Andric changeAddrMode_abs_io(const MachineInstr & MI)5140b57cec5SDimitry Andric short changeAddrMode_abs_io(const MachineInstr &MI) const { 5150b57cec5SDimitry Andric return changeAddrMode_abs_io(MI.getOpcode()); 5160b57cec5SDimitry Andric } changeAddrMode_io_abs(const MachineInstr & MI)5170b57cec5SDimitry Andric short changeAddrMode_io_abs(const MachineInstr &MI) const { 5180b57cec5SDimitry Andric return changeAddrMode_io_abs(MI.getOpcode()); 5190b57cec5SDimitry Andric } changeAddrMode_io_rr(const MachineInstr & MI)5200b57cec5SDimitry Andric short changeAddrMode_io_rr(const MachineInstr &MI) const { 5210b57cec5SDimitry Andric return changeAddrMode_io_rr(MI.getOpcode()); 5220b57cec5SDimitry Andric } changeAddrMode_rr_io(const MachineInstr & MI)5230b57cec5SDimitry Andric short changeAddrMode_rr_io(const MachineInstr &MI) const { 5240b57cec5SDimitry Andric return changeAddrMode_rr_io(MI.getOpcode()); 5250b57cec5SDimitry Andric } changeAddrMode_rr_ur(const MachineInstr & MI)5260b57cec5SDimitry Andric short changeAddrMode_rr_ur(const MachineInstr &MI) const { 5270b57cec5SDimitry Andric return changeAddrMode_rr_ur(MI.getOpcode()); 5280b57cec5SDimitry Andric } changeAddrMode_ur_rr(const MachineInstr & MI)5290b57cec5SDimitry Andric short changeAddrMode_ur_rr(const MachineInstr &MI) const { 5300b57cec5SDimitry Andric return changeAddrMode_ur_rr(MI.getOpcode()); 5310b57cec5SDimitry Andric } 5320eae32dcSDimitry Andric 5330eae32dcSDimitry Andric MCInst getNop() const override; 5340b57cec5SDimitry Andric }; 5350b57cec5SDimitry Andric 5360b57cec5SDimitry Andric } // end namespace llvm 5370b57cec5SDimitry Andric 5380b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONINSTRINFO_H 539