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" 220b57cec5SDimitry Andric #include "llvm/Support/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. 570b57cec5SDimitry Andric unsigned 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. 650b57cec5SDimitry Andric unsigned 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, 1840b57cec5SDimitry Andric MachineBasicBlock::iterator MBBI, 1855ffd83dbSDimitry Andric Register SrcReg, bool isKill, int FrameIndex, 1860b57cec5SDimitry Andric const TargetRegisterClass *RC, 1870b57cec5SDimitry Andric const TargetRegisterInfo *TRI) const override; 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric /// Load the specified register of the given register class from the specified 1900b57cec5SDimitry Andric /// stack frame index. The load instruction is to be added to the given 1910b57cec5SDimitry Andric /// machine basic block before the specified machine instruction. 1920b57cec5SDimitry Andric void loadRegFromStackSlot(MachineBasicBlock &MBB, 1930b57cec5SDimitry Andric MachineBasicBlock::iterator MBBI, 1945ffd83dbSDimitry Andric Register DestReg, int FrameIndex, 1950b57cec5SDimitry Andric const TargetRegisterClass *RC, 1960b57cec5SDimitry Andric const TargetRegisterInfo *TRI) const override; 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric /// This function is called for all pseudo instructions 1990b57cec5SDimitry Andric /// that remain after register allocation. Many pseudo instructions are 2000b57cec5SDimitry Andric /// created to help register allocation. This is the place to convert them 2010b57cec5SDimitry Andric /// into real instructions. The target can edit MI in place, or it can insert 2020b57cec5SDimitry Andric /// new instructions and erase MI. The function should return true if 2030b57cec5SDimitry Andric /// anything was changed. 2040b57cec5SDimitry Andric bool expandPostRAPseudo(MachineInstr &MI) const override; 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric /// Get the base register and byte offset of a load/store instr. 2075ffd83dbSDimitry Andric bool getMemOperandsWithOffsetWidth( 2085ffd83dbSDimitry Andric const MachineInstr &LdSt, 2095ffd83dbSDimitry Andric SmallVectorImpl<const MachineOperand *> &BaseOps, int64_t &Offset, 2105ffd83dbSDimitry Andric bool &OffsetIsScalable, unsigned &Width, 2110b57cec5SDimitry Andric const TargetRegisterInfo *TRI) const override; 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric /// Reverses the branch condition of the specified condition list, 2140b57cec5SDimitry Andric /// returning false on success and true if it cannot be reversed. 2150b57cec5SDimitry Andric bool reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) 2160b57cec5SDimitry Andric const override; 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric /// Insert a noop into the instruction stream at the specified point. 2190b57cec5SDimitry Andric void insertNoop(MachineBasicBlock &MBB, 2200b57cec5SDimitry Andric MachineBasicBlock::iterator MI) const override; 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric /// Returns true if the instruction is already predicated. 2230b57cec5SDimitry Andric bool isPredicated(const MachineInstr &MI) const override; 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric /// Return true for post-incremented instructions. 2260b57cec5SDimitry Andric bool isPostIncrement(const MachineInstr &MI) const override; 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric /// Convert the instruction into a predicated instruction. 2290b57cec5SDimitry Andric /// It returns true if the operation was successful. 2300b57cec5SDimitry Andric bool PredicateInstruction(MachineInstr &MI, 2310b57cec5SDimitry Andric ArrayRef<MachineOperand> Cond) const override; 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric /// Returns true if the first specified predicate 2340b57cec5SDimitry Andric /// subsumes the second, e.g. GE subsumes GT. 2350b57cec5SDimitry Andric bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1, 2360b57cec5SDimitry Andric ArrayRef<MachineOperand> Pred2) const override; 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric /// If the specified instruction defines any predicate 2390b57cec5SDimitry Andric /// or condition code register(s) used for predication, returns true as well 2400b57cec5SDimitry Andric /// as the definition predicate(s) by reference. 241e8d8bef9SDimitry Andric bool ClobbersPredicate(MachineInstr &MI, std::vector<MachineOperand> &Pred, 242e8d8bef9SDimitry Andric bool SkipDead) const override; 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric /// Return true if the specified instruction can be predicated. 2450b57cec5SDimitry Andric /// By default, this returns true for every instruction with a 2460b57cec5SDimitry Andric /// PredicateOperand. 2470b57cec5SDimitry Andric bool isPredicable(const MachineInstr &MI) const override; 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andric /// Test if the given instruction should be considered a scheduling boundary. 2500b57cec5SDimitry Andric /// This primarily includes labels and terminators. 2510b57cec5SDimitry Andric bool isSchedulingBoundary(const MachineInstr &MI, 2520b57cec5SDimitry Andric const MachineBasicBlock *MBB, 2530b57cec5SDimitry Andric const MachineFunction &MF) const override; 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric /// Measure the specified inline asm to determine an approximation of its 2560b57cec5SDimitry Andric /// length. 2570b57cec5SDimitry Andric unsigned getInlineAsmLength( 2580b57cec5SDimitry Andric const char *Str, 2590b57cec5SDimitry Andric const MCAsmInfo &MAI, 2600b57cec5SDimitry Andric const TargetSubtargetInfo *STI = nullptr) const override; 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric /// Allocate and return a hazard recognizer to use for this target when 2630b57cec5SDimitry Andric /// scheduling the machine instructions after register allocation. 2640b57cec5SDimitry Andric ScheduleHazardRecognizer* 2650b57cec5SDimitry Andric CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, 2660b57cec5SDimitry Andric const ScheduleDAG *DAG) const override; 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric /// For a comparison instruction, return the source registers 2690b57cec5SDimitry Andric /// in SrcReg and SrcReg2 if having two register operands, and the value it 2700b57cec5SDimitry Andric /// compares against in CmpValue. Return true if the comparison instruction 2710b57cec5SDimitry Andric /// can be analyzed. 2725ffd83dbSDimitry Andric bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, 273349cc55cSDimitry Andric Register &SrcReg2, int64_t &Mask, 274349cc55cSDimitry Andric int64_t &Value) const override; 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric /// Compute the instruction latency of a given instruction. 2770b57cec5SDimitry Andric /// If the instruction has higher cost when predicated, it's returned via 2780b57cec5SDimitry Andric /// PredCost. 2790b57cec5SDimitry Andric unsigned getInstrLatency(const InstrItineraryData *ItinData, 2800b57cec5SDimitry Andric const MachineInstr &MI, 2810b57cec5SDimitry Andric unsigned *PredCost = nullptr) const override; 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric /// Create machine specific model for scheduling. 2840b57cec5SDimitry Andric DFAPacketizer * 2850b57cec5SDimitry Andric CreateTargetScheduleState(const TargetSubtargetInfo &STI) const override; 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric // Sometimes, it is possible for the target 2880b57cec5SDimitry Andric // to tell, even without aliasing information, that two MIs access different 2890b57cec5SDimitry Andric // memory addresses. This function returns true if two MIs access different 2900b57cec5SDimitry Andric // memory addresses and false otherwise. 2910b57cec5SDimitry Andric bool 2920b57cec5SDimitry Andric areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, 2938bcb0991SDimitry Andric const MachineInstr &MIb) const override; 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric /// For instructions with a base and offset, return the position of the 2960b57cec5SDimitry Andric /// base register and offset operands. 2970b57cec5SDimitry Andric bool getBaseAndOffsetPosition(const MachineInstr &MI, unsigned &BasePos, 2980b57cec5SDimitry Andric unsigned &OffsetPos) const override; 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andric /// If the instruction is an increment of a constant value, return the amount. 3010b57cec5SDimitry Andric bool getIncrementValue(const MachineInstr &MI, int &Value) const override; 3020b57cec5SDimitry Andric 3030b57cec5SDimitry Andric /// getOperandLatency - Compute and return the use operand latency of a given 3040b57cec5SDimitry Andric /// pair of def and use. 3050b57cec5SDimitry Andric /// In most cases, the static scheduling itinerary was enough to determine the 3060b57cec5SDimitry Andric /// operand latency. But it may not be possible for instructions with variable 3070b57cec5SDimitry Andric /// number of defs / uses. 3080b57cec5SDimitry Andric /// 3090b57cec5SDimitry Andric /// This is a raw interface to the itinerary that may be directly overriden by 3100b57cec5SDimitry Andric /// a target. Use computeOperandLatency to get the best estimate of latency. 3110b57cec5SDimitry Andric int getOperandLatency(const InstrItineraryData *ItinData, 3120b57cec5SDimitry Andric const MachineInstr &DefMI, unsigned DefIdx, 3130b57cec5SDimitry Andric const MachineInstr &UseMI, 3140b57cec5SDimitry Andric unsigned UseIdx) const override; 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric /// Decompose the machine operand's target flags into two values - the direct 3170b57cec5SDimitry Andric /// target flag value and any of bit flags that are applied. 3180b57cec5SDimitry Andric std::pair<unsigned, unsigned> 3190b57cec5SDimitry Andric decomposeMachineOperandsTargetFlags(unsigned TF) const override; 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric /// Return an array that contains the direct target flag values and their 3220b57cec5SDimitry Andric /// names. 3230b57cec5SDimitry Andric /// 3240b57cec5SDimitry Andric /// MIR Serialization is able to serialize only the target flags that are 3250b57cec5SDimitry Andric /// defined by this method. 3260b57cec5SDimitry Andric ArrayRef<std::pair<unsigned, const char *>> 3270b57cec5SDimitry Andric getSerializableDirectMachineOperandTargetFlags() const override; 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric /// Return an array that contains the bitmask target flag values and their 3300b57cec5SDimitry Andric /// names. 3310b57cec5SDimitry Andric /// 3320b57cec5SDimitry Andric /// MIR Serialization is able to serialize only the target flags that are 3330b57cec5SDimitry Andric /// defined by this method. 3340b57cec5SDimitry Andric ArrayRef<std::pair<unsigned, const char *>> 3350b57cec5SDimitry Andric getSerializableBitmaskMachineOperandTargetFlags() const override; 3360b57cec5SDimitry Andric 3370b57cec5SDimitry Andric bool isTailCall(const MachineInstr &MI) const override; 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric /// HexagonInstrInfo specifics. 3400b57cec5SDimitry Andric 3410b57cec5SDimitry Andric unsigned createVR(MachineFunction *MF, MVT VT) const; 3420b57cec5SDimitry Andric MachineInstr *findLoopInstr(MachineBasicBlock *BB, unsigned EndLoopOp, 3430b57cec5SDimitry Andric MachineBasicBlock *TargetBB, 3440b57cec5SDimitry Andric SmallPtrSet<MachineBasicBlock *, 8> &Visited) const; 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric bool isAbsoluteSet(const MachineInstr &MI) const; 3470b57cec5SDimitry Andric bool isAccumulator(const MachineInstr &MI) const; 3480b57cec5SDimitry Andric bool isAddrModeWithOffset(const MachineInstr &MI) const; 3495ffd83dbSDimitry Andric bool isBaseImmOffset(const MachineInstr &MI) const; 3500b57cec5SDimitry Andric bool isComplex(const MachineInstr &MI) const; 3510b57cec5SDimitry Andric bool isCompoundBranchInstr(const MachineInstr &MI) const; 3520b57cec5SDimitry Andric bool isConstExtended(const MachineInstr &MI) const; 3530b57cec5SDimitry Andric bool isDeallocRet(const MachineInstr &MI) const; 3540b57cec5SDimitry Andric bool isDependent(const MachineInstr &ProdMI, 3550b57cec5SDimitry Andric const MachineInstr &ConsMI) const; 3560b57cec5SDimitry Andric bool isDotCurInst(const MachineInstr &MI) const; 3570b57cec5SDimitry Andric bool isDotNewInst(const MachineInstr &MI) const; 3580b57cec5SDimitry Andric bool isDuplexPair(const MachineInstr &MIa, const MachineInstr &MIb) const; 3590b57cec5SDimitry Andric bool isEarlySourceInstr(const MachineInstr &MI) const; 3600b57cec5SDimitry Andric bool isEndLoopN(unsigned Opcode) const; 3610b57cec5SDimitry Andric bool isExpr(unsigned OpType) const; 3620b57cec5SDimitry Andric bool isExtendable(const MachineInstr &MI) const; 3630b57cec5SDimitry Andric bool isExtended(const MachineInstr &MI) const; 3640b57cec5SDimitry Andric bool isFloat(const MachineInstr &MI) const; 3650b57cec5SDimitry Andric bool isHVXMemWithAIndirect(const MachineInstr &I, 3660b57cec5SDimitry Andric const MachineInstr &J) const; 3670b57cec5SDimitry Andric bool isIndirectCall(const MachineInstr &MI) const; 3680b57cec5SDimitry Andric bool isIndirectL4Return(const MachineInstr &MI) const; 3690b57cec5SDimitry Andric bool isJumpR(const MachineInstr &MI) const; 3700b57cec5SDimitry Andric bool isJumpWithinBranchRange(const MachineInstr &MI, unsigned offset) const; 3710b57cec5SDimitry Andric bool isLateInstrFeedsEarlyInstr(const MachineInstr &LRMI, 3720b57cec5SDimitry Andric const MachineInstr &ESMI) const; 3730b57cec5SDimitry Andric bool isLateResultInstr(const MachineInstr &MI) const; 3740b57cec5SDimitry Andric bool isLateSourceInstr(const MachineInstr &MI) const; 3750b57cec5SDimitry Andric bool isLoopN(const MachineInstr &MI) const; 3760b57cec5SDimitry Andric bool isMemOp(const MachineInstr &MI) const; 3770b57cec5SDimitry Andric bool isNewValue(const MachineInstr &MI) const; 3780b57cec5SDimitry Andric bool isNewValue(unsigned Opcode) const; 3790b57cec5SDimitry Andric bool isNewValueInst(const MachineInstr &MI) const; 3800b57cec5SDimitry Andric bool isNewValueJump(const MachineInstr &MI) const; 3810b57cec5SDimitry Andric bool isNewValueJump(unsigned Opcode) const; 3820b57cec5SDimitry Andric bool isNewValueStore(const MachineInstr &MI) const; 3830b57cec5SDimitry Andric bool isNewValueStore(unsigned Opcode) const; 3840b57cec5SDimitry Andric bool isOperandExtended(const MachineInstr &MI, unsigned OperandNum) const; 3850b57cec5SDimitry Andric bool isPredicatedNew(const MachineInstr &MI) const; 3860b57cec5SDimitry Andric bool isPredicatedNew(unsigned Opcode) const; 3870b57cec5SDimitry Andric bool isPredicatedTrue(const MachineInstr &MI) const; 3880b57cec5SDimitry Andric bool isPredicatedTrue(unsigned Opcode) const; 3890b57cec5SDimitry Andric bool isPredicated(unsigned Opcode) const; 3900b57cec5SDimitry Andric bool isPredicateLate(unsigned Opcode) const; 3910b57cec5SDimitry Andric bool isPredictedTaken(unsigned Opcode) const; 3925ffd83dbSDimitry Andric bool isPureSlot0(const MachineInstr &MI) const; 3935ffd83dbSDimitry Andric bool isRestrictNoSlot1Store(const MachineInstr &MI) const; 3940b57cec5SDimitry Andric bool isSaveCalleeSavedRegsCall(const MachineInstr &MI) const; 3950b57cec5SDimitry Andric bool isSignExtendingLoad(const MachineInstr &MI) const; 3960b57cec5SDimitry Andric bool isSolo(const MachineInstr &MI) const; 3970b57cec5SDimitry Andric bool isSpillPredRegOp(const MachineInstr &MI) const; 3980b57cec5SDimitry Andric bool isTC1(const MachineInstr &MI) const; 3990b57cec5SDimitry Andric bool isTC2(const MachineInstr &MI) const; 4000b57cec5SDimitry Andric bool isTC2Early(const MachineInstr &MI) const; 4010b57cec5SDimitry Andric bool isTC4x(const MachineInstr &MI) const; 4020b57cec5SDimitry Andric bool isToBeScheduledASAP(const MachineInstr &MI1, 4030b57cec5SDimitry Andric const MachineInstr &MI2) const; 4040b57cec5SDimitry Andric bool isHVXVec(const MachineInstr &MI) const; 4050b57cec5SDimitry Andric bool isValidAutoIncImm(const EVT VT, const int Offset) const; 4060b57cec5SDimitry Andric bool isValidOffset(unsigned Opcode, int Offset, 4070b57cec5SDimitry Andric const TargetRegisterInfo *TRI, bool Extend = true) const; 4080b57cec5SDimitry Andric bool isVecAcc(const MachineInstr &MI) const; 4090b57cec5SDimitry Andric bool isVecALU(const MachineInstr &MI) const; 4100b57cec5SDimitry Andric bool isVecUsableNextPacket(const MachineInstr &ProdMI, 4110b57cec5SDimitry Andric const MachineInstr &ConsMI) const; 4120b57cec5SDimitry Andric bool isZeroExtendingLoad(const MachineInstr &MI) const; 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric bool addLatencyToSchedule(const MachineInstr &MI1, 4150b57cec5SDimitry Andric const MachineInstr &MI2) const; 4160b57cec5SDimitry Andric bool canExecuteInBundle(const MachineInstr &First, 4170b57cec5SDimitry Andric const MachineInstr &Second) const; 4180b57cec5SDimitry Andric bool doesNotReturn(const MachineInstr &CallMI) const; 4190b57cec5SDimitry Andric bool hasEHLabel(const MachineBasicBlock *B) const; 4200b57cec5SDimitry Andric bool hasNonExtEquivalent(const MachineInstr &MI) const; 4210b57cec5SDimitry Andric bool hasPseudoInstrPair(const MachineInstr &MI) const; 4220b57cec5SDimitry Andric bool hasUncondBranch(const MachineBasicBlock *B) const; 4230b57cec5SDimitry Andric bool mayBeCurLoad(const MachineInstr &MI) const; 4240b57cec5SDimitry Andric bool mayBeNewStore(const MachineInstr &MI) const; 4250b57cec5SDimitry Andric bool producesStall(const MachineInstr &ProdMI, 4260b57cec5SDimitry Andric const MachineInstr &ConsMI) const; 4270b57cec5SDimitry Andric bool producesStall(const MachineInstr &MI, 4280b57cec5SDimitry Andric MachineBasicBlock::const_instr_iterator MII) const; 4290b57cec5SDimitry Andric bool predCanBeUsedAsDotNew(const MachineInstr &MI, unsigned PredReg) const; 4300b57cec5SDimitry Andric bool PredOpcodeHasJMP_c(unsigned Opcode) const; 4310b57cec5SDimitry Andric bool predOpcodeHasNot(ArrayRef<MachineOperand> Cond) const; 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric unsigned getAddrMode(const MachineInstr &MI) const; 4340b57cec5SDimitry Andric MachineOperand *getBaseAndOffset(const MachineInstr &MI, int64_t &Offset, 4350b57cec5SDimitry Andric unsigned &AccessSize) const; 4360b57cec5SDimitry Andric SmallVector<MachineInstr*,2> getBranchingInstrs(MachineBasicBlock& MBB) const; 4370b57cec5SDimitry Andric unsigned getCExtOpNum(const MachineInstr &MI) const; 4380b57cec5SDimitry Andric HexagonII::CompoundGroup 4390b57cec5SDimitry Andric getCompoundCandidateGroup(const MachineInstr &MI) const; 4400b57cec5SDimitry Andric unsigned getCompoundOpcode(const MachineInstr &GA, 4410b57cec5SDimitry Andric const MachineInstr &GB) const; 4425ffd83dbSDimitry Andric int getDuplexOpcode(const MachineInstr &MI, bool ForBigCore = true) const; 4430b57cec5SDimitry Andric int getCondOpcode(int Opc, bool sense) const; 4440b57cec5SDimitry Andric int getDotCurOp(const MachineInstr &MI) const; 4450b57cec5SDimitry Andric int getNonDotCurOp(const MachineInstr &MI) const; 4460b57cec5SDimitry Andric int getDotNewOp(const MachineInstr &MI) const; 4470b57cec5SDimitry Andric int getDotNewPredJumpOp(const MachineInstr &MI, 4480b57cec5SDimitry Andric const MachineBranchProbabilityInfo *MBPI) const; 4490b57cec5SDimitry Andric int getDotNewPredOp(const MachineInstr &MI, 4500b57cec5SDimitry Andric const MachineBranchProbabilityInfo *MBPI) const; 4510b57cec5SDimitry Andric int getDotOldOp(const MachineInstr &MI) const; 4520b57cec5SDimitry Andric HexagonII::SubInstructionGroup getDuplexCandidateGroup(const MachineInstr &MI) 4530b57cec5SDimitry Andric const; 4540b57cec5SDimitry Andric short getEquivalentHWInstr(const MachineInstr &MI) const; 4550b57cec5SDimitry Andric unsigned getInstrTimingClassLatency(const InstrItineraryData *ItinData, 4560b57cec5SDimitry Andric const MachineInstr &MI) const; 4570b57cec5SDimitry Andric bool getInvertedPredSense(SmallVectorImpl<MachineOperand> &Cond) const; 4580b57cec5SDimitry Andric unsigned getInvertedPredicatedOpcode(const int Opc) const; 4590b57cec5SDimitry Andric int getMaxValue(const MachineInstr &MI) const; 4600b57cec5SDimitry Andric unsigned getMemAccessSize(const MachineInstr &MI) const; 4610b57cec5SDimitry Andric int getMinValue(const MachineInstr &MI) const; 4620b57cec5SDimitry Andric short getNonExtOpcode(const MachineInstr &MI) const; 4630b57cec5SDimitry Andric bool getPredReg(ArrayRef<MachineOperand> Cond, unsigned &PredReg, 4640b57cec5SDimitry Andric unsigned &PredRegPos, unsigned &PredRegFlags) const; 4650b57cec5SDimitry Andric short getPseudoInstrPair(const MachineInstr &MI) const; 4660b57cec5SDimitry Andric short getRegForm(const MachineInstr &MI) const; 4670b57cec5SDimitry Andric unsigned getSize(const MachineInstr &MI) const; 4680b57cec5SDimitry Andric uint64_t getType(const MachineInstr &MI) const; 4695ffd83dbSDimitry Andric InstrStage::FuncUnits getUnits(const MachineInstr &MI) const; 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric MachineBasicBlock::instr_iterator expandVGatherPseudo(MachineInstr &MI) const; 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andric /// getInstrTimingClassLatency - Compute the instruction latency of a given 4740b57cec5SDimitry Andric /// instruction using Timing Class information, if available. 4750b57cec5SDimitry Andric unsigned nonDbgBBSize(const MachineBasicBlock *BB) const; 4760b57cec5SDimitry Andric unsigned nonDbgBundleSize(MachineBasicBlock::const_iterator BundleHead) const; 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric void immediateExtend(MachineInstr &MI) const; 4790b57cec5SDimitry Andric bool invertAndChangeJumpTarget(MachineInstr &MI, 4800b57cec5SDimitry Andric MachineBasicBlock *NewTarget) const; 4810b57cec5SDimitry Andric void genAllInsnTimingClasses(MachineFunction &MF) const; 4820b57cec5SDimitry Andric bool reversePredSense(MachineInstr &MI) const; 4830b57cec5SDimitry Andric unsigned reversePrediction(unsigned Opcode) const; 4840b57cec5SDimitry Andric bool validateBranchCond(const ArrayRef<MachineOperand> &Cond) const; 4850b57cec5SDimitry Andric 4860b57cec5SDimitry Andric void setBundleNoShuf(MachineBasicBlock::instr_iterator MIB) const; 4870b57cec5SDimitry Andric bool getBundleNoShuf(const MachineInstr &MIB) const; 4885ffd83dbSDimitry Andric 4895ffd83dbSDimitry Andric // When TinyCore with Duplexes is enabled, this function is used to translate 4905ffd83dbSDimitry Andric // tiny-instructions to big-instructions and vice versa to get the slot 4915ffd83dbSDimitry Andric // consumption. 4925ffd83dbSDimitry Andric void changeDuplexOpcode(MachineBasicBlock::instr_iterator MII, 4935ffd83dbSDimitry Andric bool ToBigInstrs) const; 4945ffd83dbSDimitry Andric void translateInstrsForDup(MachineFunction &MF, 4955ffd83dbSDimitry Andric bool ToBigInstrs = true) const; 4965ffd83dbSDimitry Andric void translateInstrsForDup(MachineBasicBlock::instr_iterator MII, 4975ffd83dbSDimitry Andric bool ToBigInstrs) const; 4985ffd83dbSDimitry Andric 4990b57cec5SDimitry Andric // Addressing mode relations. 5000b57cec5SDimitry Andric short changeAddrMode_abs_io(short Opc) const; 5010b57cec5SDimitry Andric short changeAddrMode_io_abs(short Opc) const; 5020b57cec5SDimitry Andric short changeAddrMode_io_pi(short Opc) const; 5030b57cec5SDimitry Andric short changeAddrMode_io_rr(short Opc) const; 5040b57cec5SDimitry Andric short changeAddrMode_pi_io(short Opc) const; 5050b57cec5SDimitry Andric short changeAddrMode_rr_io(short Opc) const; 5060b57cec5SDimitry Andric short changeAddrMode_rr_ur(short Opc) const; 5070b57cec5SDimitry Andric short changeAddrMode_ur_rr(short Opc) const; 5080b57cec5SDimitry Andric 5090b57cec5SDimitry Andric short changeAddrMode_abs_io(const MachineInstr &MI) const { 5100b57cec5SDimitry Andric return changeAddrMode_abs_io(MI.getOpcode()); 5110b57cec5SDimitry Andric } 5120b57cec5SDimitry Andric short changeAddrMode_io_abs(const MachineInstr &MI) const { 5130b57cec5SDimitry Andric return changeAddrMode_io_abs(MI.getOpcode()); 5140b57cec5SDimitry Andric } 5150b57cec5SDimitry Andric short changeAddrMode_io_rr(const MachineInstr &MI) const { 5160b57cec5SDimitry Andric return changeAddrMode_io_rr(MI.getOpcode()); 5170b57cec5SDimitry Andric } 5180b57cec5SDimitry Andric short changeAddrMode_rr_io(const MachineInstr &MI) const { 5190b57cec5SDimitry Andric return changeAddrMode_rr_io(MI.getOpcode()); 5200b57cec5SDimitry Andric } 5210b57cec5SDimitry Andric short changeAddrMode_rr_ur(const MachineInstr &MI) const { 5220b57cec5SDimitry Andric return changeAddrMode_rr_ur(MI.getOpcode()); 5230b57cec5SDimitry Andric } 5240b57cec5SDimitry Andric short changeAddrMode_ur_rr(const MachineInstr &MI) const { 5250b57cec5SDimitry Andric return changeAddrMode_ur_rr(MI.getOpcode()); 5260b57cec5SDimitry Andric } 527*0eae32dcSDimitry Andric 528*0eae32dcSDimitry Andric MCInst getNop() const override; 5290b57cec5SDimitry Andric }; 5300b57cec5SDimitry Andric 5310b57cec5SDimitry Andric } // end namespace llvm 5320b57cec5SDimitry Andric 5330b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONINSTRINFO_H 534