xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Hexagon/HexagonInstrInfo.h (revision 0eae32dcef82f6f06de6419a0d623d7def0cc8f6)
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