10b57cec5SDimitry Andric //===-- PPCInstrInfo.h - PowerPC 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 PowerPC implementation of the TargetInstrInfo class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_POWERPC_PPCINSTRINFO_H 140b57cec5SDimitry Andric #define LLVM_LIB_TARGET_POWERPC_PPCINSTRINFO_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "PPCRegisterInfo.h" 170b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric #define GET_INSTRINFO_HEADER 200b57cec5SDimitry Andric #include "PPCGenInstrInfo.inc" 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric namespace llvm { 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric /// PPCII - This namespace holds all of the PowerPC target-specific 250b57cec5SDimitry Andric /// per-instruction flags. These must match the corresponding definitions in 260b57cec5SDimitry Andric /// PPC.td and PPCInstrFormats.td. 270b57cec5SDimitry Andric namespace PPCII { 280b57cec5SDimitry Andric enum { 290b57cec5SDimitry Andric // PPC970 Instruction Flags. These flags describe the characteristics of the 300b57cec5SDimitry Andric // PowerPC 970 (aka G5) dispatch groups and how they are formed out of 310b57cec5SDimitry Andric // raw machine instructions. 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric /// PPC970_First - This instruction starts a new dispatch group, so it will 340b57cec5SDimitry Andric /// always be the first one in the group. 350b57cec5SDimitry Andric PPC970_First = 0x1, 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric /// PPC970_Single - This instruction starts a new dispatch group and 380b57cec5SDimitry Andric /// terminates it, so it will be the sole instruction in the group. 390b57cec5SDimitry Andric PPC970_Single = 0x2, 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric /// PPC970_Cracked - This instruction is cracked into two pieces, requiring 420b57cec5SDimitry Andric /// two dispatch pipes to be available to issue. 430b57cec5SDimitry Andric PPC970_Cracked = 0x4, 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric /// PPC970_Mask/Shift - This is a bitmask that selects the pipeline type that 460b57cec5SDimitry Andric /// an instruction is issued to. 470b57cec5SDimitry Andric PPC970_Shift = 3, 480b57cec5SDimitry Andric PPC970_Mask = 0x07 << PPC970_Shift 490b57cec5SDimitry Andric }; 500b57cec5SDimitry Andric enum PPC970_Unit { 510b57cec5SDimitry Andric /// These are the various PPC970 execution unit pipelines. Each instruction 520b57cec5SDimitry Andric /// is one of these. 530b57cec5SDimitry Andric PPC970_Pseudo = 0 << PPC970_Shift, // Pseudo instruction 540b57cec5SDimitry Andric PPC970_FXU = 1 << PPC970_Shift, // Fixed Point (aka Integer/ALU) Unit 550b57cec5SDimitry Andric PPC970_LSU = 2 << PPC970_Shift, // Load Store Unit 560b57cec5SDimitry Andric PPC970_FPU = 3 << PPC970_Shift, // Floating Point Unit 570b57cec5SDimitry Andric PPC970_CRU = 4 << PPC970_Shift, // Control Register Unit 580b57cec5SDimitry Andric PPC970_VALU = 5 << PPC970_Shift, // Vector ALU 590b57cec5SDimitry Andric PPC970_VPERM = 6 << PPC970_Shift, // Vector Permute Unit 600b57cec5SDimitry Andric PPC970_BRU = 7 << PPC970_Shift // Branch Unit 610b57cec5SDimitry Andric }; 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric enum { 640b57cec5SDimitry Andric /// Shift count to bypass PPC970 flags 650b57cec5SDimitry Andric NewDef_Shift = 6, 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric /// This instruction is an X-Form memory operation. 680b57cec5SDimitry Andric XFormMemOp = 0x1 << (NewDef_Shift+1) 690b57cec5SDimitry Andric }; 700b57cec5SDimitry Andric } // end namespace PPCII 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric // Instructions that have an immediate form might be convertible to that 730b57cec5SDimitry Andric // form if the correct input is a result of a load immediate. In order to 740b57cec5SDimitry Andric // know whether the transformation is special, we might need to know some 750b57cec5SDimitry Andric // of the details of the two forms. 760b57cec5SDimitry Andric struct ImmInstrInfo { 770b57cec5SDimitry Andric // Is the immediate field in the immediate form signed or unsigned? 780b57cec5SDimitry Andric uint64_t SignedImm : 1; 790b57cec5SDimitry Andric // Does the immediate need to be a multiple of some value? 800b57cec5SDimitry Andric uint64_t ImmMustBeMultipleOf : 5; 810b57cec5SDimitry Andric // Is R0/X0 treated specially by the original r+r instruction? 820b57cec5SDimitry Andric // If so, in which operand? 830b57cec5SDimitry Andric uint64_t ZeroIsSpecialOrig : 3; 840b57cec5SDimitry Andric // Is R0/X0 treated specially by the new r+i instruction? 850b57cec5SDimitry Andric // If so, in which operand? 860b57cec5SDimitry Andric uint64_t ZeroIsSpecialNew : 3; 870b57cec5SDimitry Andric // Is the operation commutative? 880b57cec5SDimitry Andric uint64_t IsCommutative : 1; 890b57cec5SDimitry Andric // The operand number to check for add-immediate def. 900b57cec5SDimitry Andric uint64_t OpNoForForwarding : 3; 910b57cec5SDimitry Andric // The operand number for the immediate. 920b57cec5SDimitry Andric uint64_t ImmOpNo : 3; 930b57cec5SDimitry Andric // The opcode of the new instruction. 940b57cec5SDimitry Andric uint64_t ImmOpcode : 16; 950b57cec5SDimitry Andric // The size of the immediate. 960b57cec5SDimitry Andric uint64_t ImmWidth : 5; 970b57cec5SDimitry Andric // The immediate should be truncated to N bits. 980b57cec5SDimitry Andric uint64_t TruncateImmTo : 5; 990b57cec5SDimitry Andric // Is the instruction summing the operand 1000b57cec5SDimitry Andric uint64_t IsSummingOperands : 1; 1010b57cec5SDimitry Andric }; 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric // Information required to convert an instruction to just a materialized 1040b57cec5SDimitry Andric // immediate. 1050b57cec5SDimitry Andric struct LoadImmediateInfo { 1060b57cec5SDimitry Andric unsigned Imm : 16; 1070b57cec5SDimitry Andric unsigned Is64Bit : 1; 1080b57cec5SDimitry Andric unsigned SetCR : 1; 1090b57cec5SDimitry Andric }; 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric class PPCSubtarget; 1120b57cec5SDimitry Andric class PPCInstrInfo : public PPCGenInstrInfo { 1130b57cec5SDimitry Andric PPCSubtarget &Subtarget; 1140b57cec5SDimitry Andric const PPCRegisterInfo RI; 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric void StoreRegToStackSlot(MachineFunction &MF, unsigned SrcReg, bool isKill, 1170b57cec5SDimitry Andric int FrameIdx, const TargetRegisterClass *RC, 1180b57cec5SDimitry Andric SmallVectorImpl<MachineInstr *> &NewMIs) const; 1190b57cec5SDimitry Andric void LoadRegFromStackSlot(MachineFunction &MF, const DebugLoc &DL, 1200b57cec5SDimitry Andric unsigned DestReg, int FrameIdx, 1210b57cec5SDimitry Andric const TargetRegisterClass *RC, 1220b57cec5SDimitry Andric SmallVectorImpl<MachineInstr *> &NewMIs) const; 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric // If the inst has imm-form and one of its operand is produced by a LI, 1250b57cec5SDimitry Andric // put the imm into the inst directly and remove the LI if possible. 1260b57cec5SDimitry Andric bool transformToImmFormFedByLI(MachineInstr &MI, const ImmInstrInfo &III, 1270b57cec5SDimitry Andric unsigned ConstantOpNo, MachineInstr &DefMI, 1280b57cec5SDimitry Andric int64_t Imm) const; 1290b57cec5SDimitry Andric // If the inst has imm-form and one of its operand is produced by an 1300b57cec5SDimitry Andric // add-immediate, try to transform it when possible. 1310b57cec5SDimitry Andric bool transformToImmFormFedByAdd(MachineInstr &MI, const ImmInstrInfo &III, 1320b57cec5SDimitry Andric unsigned ConstantOpNo, MachineInstr &DefMI, 1330b57cec5SDimitry Andric bool KillDefMI) const; 1340b57cec5SDimitry Andric // Try to find that, if the instruction 'MI' contains any operand that 1350b57cec5SDimitry Andric // could be forwarded from some inst that feeds it. If yes, return the 1360b57cec5SDimitry Andric // Def of that operand. And OpNoForForwarding is the operand index in 1370b57cec5SDimitry Andric // the 'MI' for that 'Def'. If we see another use of this Def between 1380b57cec5SDimitry Andric // the Def and the MI, SeenIntermediateUse becomes 'true'. 1390b57cec5SDimitry Andric MachineInstr *getForwardingDefMI(MachineInstr &MI, 1400b57cec5SDimitry Andric unsigned &OpNoForForwarding, 1410b57cec5SDimitry Andric bool &SeenIntermediateUse) const; 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric // Can the user MI have it's source at index \p OpNoForForwarding 1440b57cec5SDimitry Andric // forwarded from an add-immediate that feeds it? 1450b57cec5SDimitry Andric bool isUseMIElgibleForForwarding(MachineInstr &MI, const ImmInstrInfo &III, 1460b57cec5SDimitry Andric unsigned OpNoForForwarding) const; 1470b57cec5SDimitry Andric bool isDefMIElgibleForForwarding(MachineInstr &DefMI, 1480b57cec5SDimitry Andric const ImmInstrInfo &III, 1490b57cec5SDimitry Andric MachineOperand *&ImmMO, 1500b57cec5SDimitry Andric MachineOperand *&RegMO) const; 1510b57cec5SDimitry Andric bool isImmElgibleForForwarding(const MachineOperand &ImmMO, 1520b57cec5SDimitry Andric const MachineInstr &DefMI, 1530b57cec5SDimitry Andric const ImmInstrInfo &III, 1540b57cec5SDimitry Andric int64_t &Imm) const; 1550b57cec5SDimitry Andric bool isRegElgibleForForwarding(const MachineOperand &RegMO, 1560b57cec5SDimitry Andric const MachineInstr &DefMI, 1570b57cec5SDimitry Andric const MachineInstr &MI, bool KillDefMI, 1580b57cec5SDimitry Andric bool &IsFwdFeederRegKilled) const; 1590b57cec5SDimitry Andric const unsigned *getStoreOpcodesForSpillArray() const; 1600b57cec5SDimitry Andric const unsigned *getLoadOpcodesForSpillArray() const; 1610b57cec5SDimitry Andric virtual void anchor(); 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric protected: 1640b57cec5SDimitry Andric /// Commutes the operands in the given instruction. 1650b57cec5SDimitry Andric /// The commutable operands are specified by their indices OpIdx1 and OpIdx2. 1660b57cec5SDimitry Andric /// 1670b57cec5SDimitry Andric /// Do not call this method for a non-commutable instruction or for 1680b57cec5SDimitry Andric /// non-commutable pair of operand indices OpIdx1 and OpIdx2. 1690b57cec5SDimitry Andric /// Even though the instruction is commutable, the method may still 1700b57cec5SDimitry Andric /// fail to commute the operands, null pointer is returned in such cases. 1710b57cec5SDimitry Andric /// 1720b57cec5SDimitry Andric /// For example, we can commute rlwimi instructions, but only if the 1730b57cec5SDimitry Andric /// rotate amt is zero. We also have to munge the immediates a bit. 1740b57cec5SDimitry Andric MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI, 1750b57cec5SDimitry Andric unsigned OpIdx1, 1760b57cec5SDimitry Andric unsigned OpIdx2) const override; 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric public: 1790b57cec5SDimitry Andric explicit PPCInstrInfo(PPCSubtarget &STI); 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As 1820b57cec5SDimitry Andric /// such, whenever a client has an instance of instruction info, it should 1830b57cec5SDimitry Andric /// always be able to get register info as well (through this method). 1840b57cec5SDimitry Andric /// 1850b57cec5SDimitry Andric const PPCRegisterInfo &getRegisterInfo() const { return RI; } 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric bool isXFormMemOp(unsigned Opcode) const { 1880b57cec5SDimitry Andric return get(Opcode).TSFlags & PPCII::XFormMemOp; 1890b57cec5SDimitry Andric } 1900b57cec5SDimitry Andric static bool isSameClassPhysRegCopy(unsigned Opcode) { 1910b57cec5SDimitry Andric unsigned CopyOpcodes[] = 1920b57cec5SDimitry Andric { PPC::OR, PPC::OR8, PPC::FMR, PPC::VOR, PPC::XXLOR, PPC::XXLORf, 1930b57cec5SDimitry Andric PPC::XSCPSGNDP, PPC::MCRF, PPC::QVFMR, PPC::QVFMRs, PPC::QVFMRb, 1940b57cec5SDimitry Andric PPC::CROR, PPC::EVOR, -1U }; 1950b57cec5SDimitry Andric for (int i = 0; CopyOpcodes[i] != -1U; i++) 1960b57cec5SDimitry Andric if (Opcode == CopyOpcodes[i]) 1970b57cec5SDimitry Andric return true; 1980b57cec5SDimitry Andric return false; 1990b57cec5SDimitry Andric } 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric ScheduleHazardRecognizer * 2020b57cec5SDimitry Andric CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, 2030b57cec5SDimitry Andric const ScheduleDAG *DAG) const override; 2040b57cec5SDimitry Andric ScheduleHazardRecognizer * 2050b57cec5SDimitry Andric CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, 2060b57cec5SDimitry Andric const ScheduleDAG *DAG) const override; 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andric unsigned getInstrLatency(const InstrItineraryData *ItinData, 2090b57cec5SDimitry Andric const MachineInstr &MI, 2100b57cec5SDimitry Andric unsigned *PredCost = nullptr) const override; 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric int getOperandLatency(const InstrItineraryData *ItinData, 2130b57cec5SDimitry Andric const MachineInstr &DefMI, unsigned DefIdx, 2140b57cec5SDimitry Andric const MachineInstr &UseMI, 2150b57cec5SDimitry Andric unsigned UseIdx) const override; 2160b57cec5SDimitry Andric int getOperandLatency(const InstrItineraryData *ItinData, 2170b57cec5SDimitry Andric SDNode *DefNode, unsigned DefIdx, 2180b57cec5SDimitry Andric SDNode *UseNode, unsigned UseIdx) const override { 2190b57cec5SDimitry Andric return PPCGenInstrInfo::getOperandLatency(ItinData, DefNode, DefIdx, 2200b57cec5SDimitry Andric UseNode, UseIdx); 2210b57cec5SDimitry Andric } 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric bool hasLowDefLatency(const TargetSchedModel &SchedModel, 2240b57cec5SDimitry Andric const MachineInstr &DefMI, 2250b57cec5SDimitry Andric unsigned DefIdx) const override { 2260b57cec5SDimitry Andric // Machine LICM should hoist all instructions in low-register-pressure 2270b57cec5SDimitry Andric // situations; none are sufficiently free to justify leaving in a loop 2280b57cec5SDimitry Andric // body. 2290b57cec5SDimitry Andric return false; 2300b57cec5SDimitry Andric } 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric bool useMachineCombiner() const override { 2330b57cec5SDimitry Andric return true; 2340b57cec5SDimitry Andric } 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric /// Return true when there is potentially a faster code sequence 2370b57cec5SDimitry Andric /// for an instruction chain ending in <Root>. All potential patterns are 2380b57cec5SDimitry Andric /// output in the <Pattern> array. 2390b57cec5SDimitry Andric bool getMachineCombinerPatterns( 2400b57cec5SDimitry Andric MachineInstr &Root, 2410b57cec5SDimitry Andric SmallVectorImpl<MachineCombinerPattern> &P) const override; 2420b57cec5SDimitry Andric 2430b57cec5SDimitry Andric bool isAssociativeAndCommutative(const MachineInstr &Inst) const override; 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric bool isCoalescableExtInstr(const MachineInstr &MI, 2460b57cec5SDimitry Andric unsigned &SrcReg, unsigned &DstReg, 2470b57cec5SDimitry Andric unsigned &SubIdx) const override; 2480b57cec5SDimitry Andric unsigned isLoadFromStackSlot(const MachineInstr &MI, 2490b57cec5SDimitry Andric int &FrameIndex) const override; 2500b57cec5SDimitry Andric bool isReallyTriviallyReMaterializable(const MachineInstr &MI, 251*8bcb0991SDimitry Andric AAResults *AA) const override; 2520b57cec5SDimitry Andric unsigned isStoreToStackSlot(const MachineInstr &MI, 2530b57cec5SDimitry Andric int &FrameIndex) const override; 2540b57cec5SDimitry Andric 255*8bcb0991SDimitry Andric bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, 2560b57cec5SDimitry Andric unsigned &SrcOpIdx2) const override; 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric void insertNoop(MachineBasicBlock &MBB, 2590b57cec5SDimitry Andric MachineBasicBlock::iterator MI) const override; 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric // Branch analysis. 2630b57cec5SDimitry Andric bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 2640b57cec5SDimitry Andric MachineBasicBlock *&FBB, 2650b57cec5SDimitry Andric SmallVectorImpl<MachineOperand> &Cond, 2660b57cec5SDimitry Andric bool AllowModify) const override; 2670b57cec5SDimitry Andric unsigned removeBranch(MachineBasicBlock &MBB, 2680b57cec5SDimitry Andric int *BytesRemoved = nullptr) const override; 2690b57cec5SDimitry Andric unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 2700b57cec5SDimitry Andric MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, 2710b57cec5SDimitry Andric const DebugLoc &DL, 2720b57cec5SDimitry Andric int *BytesAdded = nullptr) const override; 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric // Select analysis. 2750b57cec5SDimitry Andric bool canInsertSelect(const MachineBasicBlock &, ArrayRef<MachineOperand> Cond, 2760b57cec5SDimitry Andric unsigned, unsigned, int &, int &, int &) const override; 2770b57cec5SDimitry Andric void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 2780b57cec5SDimitry Andric const DebugLoc &DL, unsigned DstReg, 2790b57cec5SDimitry Andric ArrayRef<MachineOperand> Cond, unsigned TrueReg, 2800b57cec5SDimitry Andric unsigned FalseReg) const override; 2810b57cec5SDimitry Andric 2820b57cec5SDimitry Andric void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 2830b57cec5SDimitry Andric const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, 2840b57cec5SDimitry Andric bool KillSrc) const override; 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric void storeRegToStackSlot(MachineBasicBlock &MBB, 2870b57cec5SDimitry Andric MachineBasicBlock::iterator MBBI, 2880b57cec5SDimitry Andric unsigned SrcReg, bool isKill, int FrameIndex, 2890b57cec5SDimitry Andric const TargetRegisterClass *RC, 2900b57cec5SDimitry Andric const TargetRegisterInfo *TRI) const override; 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric void loadRegFromStackSlot(MachineBasicBlock &MBB, 2930b57cec5SDimitry Andric MachineBasicBlock::iterator MBBI, 2940b57cec5SDimitry Andric unsigned DestReg, int FrameIndex, 2950b57cec5SDimitry Andric const TargetRegisterClass *RC, 2960b57cec5SDimitry Andric const TargetRegisterInfo *TRI) const override; 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric unsigned getStoreOpcodeForSpill(unsigned Reg, 2990b57cec5SDimitry Andric const TargetRegisterClass *RC = nullptr) const; 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric unsigned getLoadOpcodeForSpill(unsigned Reg, 3020b57cec5SDimitry Andric const TargetRegisterClass *RC = nullptr) const; 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric bool 3050b57cec5SDimitry Andric reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; 3060b57cec5SDimitry Andric 3070b57cec5SDimitry Andric bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg, 3080b57cec5SDimitry Andric MachineRegisterInfo *MRI) const override; 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric // If conversion by predication (only supported by some branch instructions). 3110b57cec5SDimitry Andric // All of the profitability checks always return true; it is always 3120b57cec5SDimitry Andric // profitable to use the predicated branches. 3130b57cec5SDimitry Andric bool isProfitableToIfCvt(MachineBasicBlock &MBB, 3140b57cec5SDimitry Andric unsigned NumCycles, unsigned ExtraPredCycles, 3150b57cec5SDimitry Andric BranchProbability Probability) const override { 3160b57cec5SDimitry Andric return true; 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric bool isProfitableToIfCvt(MachineBasicBlock &TMBB, 3200b57cec5SDimitry Andric unsigned NumT, unsigned ExtraT, 3210b57cec5SDimitry Andric MachineBasicBlock &FMBB, 3220b57cec5SDimitry Andric unsigned NumF, unsigned ExtraF, 3230b57cec5SDimitry Andric BranchProbability Probability) const override; 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, 3260b57cec5SDimitry Andric BranchProbability Probability) const override { 3270b57cec5SDimitry Andric return true; 3280b57cec5SDimitry Andric } 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric bool isProfitableToUnpredicate(MachineBasicBlock &TMBB, 3310b57cec5SDimitry Andric MachineBasicBlock &FMBB) const override { 3320b57cec5SDimitry Andric return false; 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric // Predication support. 3360b57cec5SDimitry Andric bool isPredicated(const MachineInstr &MI) const override; 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric bool isUnpredicatedTerminator(const MachineInstr &MI) const override; 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric bool PredicateInstruction(MachineInstr &MI, 3410b57cec5SDimitry Andric ArrayRef<MachineOperand> Pred) const override; 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1, 3440b57cec5SDimitry Andric ArrayRef<MachineOperand> Pred2) const override; 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric bool DefinesPredicate(MachineInstr &MI, 3470b57cec5SDimitry Andric std::vector<MachineOperand> &Pred) const override; 3480b57cec5SDimitry Andric 3490b57cec5SDimitry Andric bool isPredicable(const MachineInstr &MI) const override; 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andric // Comparison optimization. 3520b57cec5SDimitry Andric 3530b57cec5SDimitry Andric bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, 3540b57cec5SDimitry Andric unsigned &SrcReg2, int &Mask, int &Value) const override; 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric bool optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg, 3570b57cec5SDimitry Andric unsigned SrcReg2, int Mask, int Value, 3580b57cec5SDimitry Andric const MachineRegisterInfo *MRI) const override; 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric /// Return true if get the base operand, byte offset of an instruction and 3620b57cec5SDimitry Andric /// the memory width. Width is the size of memory that is being 3630b57cec5SDimitry Andric /// loaded/stored (e.g. 1, 2, 4, 8). 3640b57cec5SDimitry Andric bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, 3650b57cec5SDimitry Andric const MachineOperand *&BaseOp, 3660b57cec5SDimitry Andric int64_t &Offset, unsigned &Width, 3670b57cec5SDimitry Andric const TargetRegisterInfo *TRI) const; 3680b57cec5SDimitry Andric 3690b57cec5SDimitry Andric /// Return true if two MIs access different memory addresses and false 3700b57cec5SDimitry Andric /// otherwise 3710b57cec5SDimitry Andric bool 3720b57cec5SDimitry Andric areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, 373*8bcb0991SDimitry Andric const MachineInstr &MIb) const override; 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric /// GetInstSize - Return the number of bytes of code the specified 3760b57cec5SDimitry Andric /// instruction may be. This returns the maximum number of bytes. 3770b57cec5SDimitry Andric /// 3780b57cec5SDimitry Andric unsigned getInstSizeInBytes(const MachineInstr &MI) const override; 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric void getNoop(MCInst &NopInst) const override; 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andric std::pair<unsigned, unsigned> 3830b57cec5SDimitry Andric decomposeMachineOperandsTargetFlags(unsigned TF) const override; 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric ArrayRef<std::pair<unsigned, const char *>> 3860b57cec5SDimitry Andric getSerializableDirectMachineOperandTargetFlags() const override; 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric ArrayRef<std::pair<unsigned, const char *>> 3890b57cec5SDimitry Andric getSerializableBitmaskMachineOperandTargetFlags() const override; 3900b57cec5SDimitry Andric 3910b57cec5SDimitry Andric // Expand VSX Memory Pseudo instruction to either a VSX or a FP instruction. 3920b57cec5SDimitry Andric bool expandVSXMemPseudo(MachineInstr &MI) const; 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric // Lower pseudo instructions after register allocation. 3950b57cec5SDimitry Andric bool expandPostRAPseudo(MachineInstr &MI) const override; 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric static bool isVFRegister(unsigned Reg) { 3980b57cec5SDimitry Andric return Reg >= PPC::VF0 && Reg <= PPC::VF31; 3990b57cec5SDimitry Andric } 4000b57cec5SDimitry Andric static bool isVRRegister(unsigned Reg) { 4010b57cec5SDimitry Andric return Reg >= PPC::V0 && Reg <= PPC::V31; 4020b57cec5SDimitry Andric } 4030b57cec5SDimitry Andric const TargetRegisterClass *updatedRC(const TargetRegisterClass *RC) const; 4040b57cec5SDimitry Andric static int getRecordFormOpcode(unsigned Opcode); 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andric bool isTOCSaveMI(const MachineInstr &MI) const; 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric bool isSignOrZeroExtended(const MachineInstr &MI, bool SignExt, 4090b57cec5SDimitry Andric const unsigned PhiDepth) const; 4100b57cec5SDimitry Andric 4110b57cec5SDimitry Andric /// Return true if the output of the instruction is always a sign-extended, 4120b57cec5SDimitry Andric /// i.e. 0 to 31-th bits are same as 32-th bit. 4130b57cec5SDimitry Andric bool isSignExtended(const MachineInstr &MI, const unsigned depth = 0) const { 4140b57cec5SDimitry Andric return isSignOrZeroExtended(MI, true, depth); 4150b57cec5SDimitry Andric } 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric /// Return true if the output of the instruction is always zero-extended, 4180b57cec5SDimitry Andric /// i.e. 0 to 31-th bits are all zeros 4190b57cec5SDimitry Andric bool isZeroExtended(const MachineInstr &MI, const unsigned depth = 0) const { 4200b57cec5SDimitry Andric return isSignOrZeroExtended(MI, false, depth); 4210b57cec5SDimitry Andric } 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric bool convertToImmediateForm(MachineInstr &MI, 4240b57cec5SDimitry Andric MachineInstr **KilledDef = nullptr) const; 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric /// Fixup killed/dead flag for register \p RegNo between instructions [\p 4270b57cec5SDimitry Andric /// StartMI, \p EndMI]. Some PostRA transformations may violate register 4280b57cec5SDimitry Andric /// killed/dead flags semantics, this function can be called to fix up. Before 4290b57cec5SDimitry Andric /// calling this function, 4300b57cec5SDimitry Andric /// 1. Ensure that \p RegNo liveness is killed after instruction \p EndMI. 4310b57cec5SDimitry Andric /// 2. Ensure that there is no new definition between (\p StartMI, \p EndMI) 4320b57cec5SDimitry Andric /// and possible definition for \p RegNo is \p StartMI or \p EndMI. 4330b57cec5SDimitry Andric /// 3. Ensure that all instructions between [\p StartMI, \p EndMI] are in same 4340b57cec5SDimitry Andric /// basic block. 4350b57cec5SDimitry Andric void fixupIsDeadOrKill(MachineInstr &StartMI, MachineInstr &EndMI, 4360b57cec5SDimitry Andric unsigned RegNo) const; 4370b57cec5SDimitry Andric void replaceInstrWithLI(MachineInstr &MI, const LoadImmediateInfo &LII) const; 4380b57cec5SDimitry Andric void replaceInstrOperandWithImm(MachineInstr &MI, unsigned OpNo, 4390b57cec5SDimitry Andric int64_t Imm) const; 4400b57cec5SDimitry Andric 441*8bcb0991SDimitry Andric bool instrHasImmForm(unsigned Opc, bool IsVFReg, ImmInstrInfo &III, 4420b57cec5SDimitry Andric bool PostRA) const; 4430b57cec5SDimitry Andric 444*8bcb0991SDimitry Andric // In PostRA phase, try to find instruction defines \p Reg before \p MI. 445*8bcb0991SDimitry Andric // \p SeenIntermediate is set to true if uses between DefMI and \p MI exist. 446*8bcb0991SDimitry Andric MachineInstr *getDefMIPostRA(unsigned Reg, MachineInstr &MI, 447*8bcb0991SDimitry Andric bool &SeenIntermediateUse) const; 448*8bcb0991SDimitry Andric 4490b57cec5SDimitry Andric /// getRegNumForOperand - some operands use different numbering schemes 4500b57cec5SDimitry Andric /// for the same registers. For example, a VSX instruction may have any of 4510b57cec5SDimitry Andric /// vs0-vs63 allocated whereas an Altivec instruction could only have 4520b57cec5SDimitry Andric /// vs32-vs63 allocated (numbered as v0-v31). This function returns the actual 4530b57cec5SDimitry Andric /// register number needed for the opcode/operand number combination. 4540b57cec5SDimitry Andric /// The operand number argument will be useful when we need to extend this 4550b57cec5SDimitry Andric /// to instructions that use both Altivec and VSX numbering (for different 4560b57cec5SDimitry Andric /// operands). 4570b57cec5SDimitry Andric static unsigned getRegNumForOperand(const MCInstrDesc &Desc, unsigned Reg, 4580b57cec5SDimitry Andric unsigned OpNo) { 4590b57cec5SDimitry Andric int16_t regClass = Desc.OpInfo[OpNo].RegClass; 4600b57cec5SDimitry Andric switch (regClass) { 4610b57cec5SDimitry Andric // We store F0-F31, VF0-VF31 in MCOperand and it should be F0-F31, 4620b57cec5SDimitry Andric // VSX32-VSX63 during encoding/disassembling 4630b57cec5SDimitry Andric case PPC::VSSRCRegClassID: 4640b57cec5SDimitry Andric case PPC::VSFRCRegClassID: 4650b57cec5SDimitry Andric if (isVFRegister(Reg)) 4660b57cec5SDimitry Andric return PPC::VSX32 + (Reg - PPC::VF0); 4670b57cec5SDimitry Andric break; 4680b57cec5SDimitry Andric // We store VSL0-VSL31, V0-V31 in MCOperand and it should be VSL0-VSL31, 4690b57cec5SDimitry Andric // VSX32-VSX63 during encoding/disassembling 4700b57cec5SDimitry Andric case PPC::VSRCRegClassID: 4710b57cec5SDimitry Andric if (isVRRegister(Reg)) 4720b57cec5SDimitry Andric return PPC::VSX32 + (Reg - PPC::V0); 4730b57cec5SDimitry Andric break; 4740b57cec5SDimitry Andric // Other RegClass doesn't need mapping 4750b57cec5SDimitry Andric default: 4760b57cec5SDimitry Andric break; 4770b57cec5SDimitry Andric } 4780b57cec5SDimitry Andric return Reg; 4790b57cec5SDimitry Andric } 4800b57cec5SDimitry Andric 4810b57cec5SDimitry Andric /// Check \p Opcode is BDNZ (Decrement CTR and branch if it is still nonzero). 4820b57cec5SDimitry Andric bool isBDNZ(unsigned Opcode) const; 4830b57cec5SDimitry Andric 4840b57cec5SDimitry Andric /// Find the hardware loop instruction used to set-up the specified loop. 4850b57cec5SDimitry Andric /// On PPC, we have two instructions used to set-up the hardware loop 4860b57cec5SDimitry Andric /// (MTCTRloop, MTCTR8loop) with corresponding endloop (BDNZ, BDNZ8) 4870b57cec5SDimitry Andric /// instructions to indicate the end of a loop. 488*8bcb0991SDimitry Andric MachineInstr * 489*8bcb0991SDimitry Andric findLoopInstr(MachineBasicBlock &PreHeader, 490*8bcb0991SDimitry Andric SmallPtrSet<MachineBasicBlock *, 8> &Visited) const; 4910b57cec5SDimitry Andric 492*8bcb0991SDimitry Andric /// Analyze loop L, which must be a single-basic-block loop, and if the 493*8bcb0991SDimitry Andric /// conditions can be understood enough produce a PipelinerLoopInfo object. 494*8bcb0991SDimitry Andric std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo> 495*8bcb0991SDimitry Andric analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override; 4960b57cec5SDimitry Andric }; 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric } 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric #endif 501