1*9880d681SAndroid Build Coastguard Worker //===-- MipsInstrInfo.h - Mips Instruction Information ----------*- C++ -*-===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // This file contains the Mips implementation of the TargetInstrInfo class. 11*9880d681SAndroid Build Coastguard Worker // 12*9880d681SAndroid Build Coastguard Worker // FIXME: We need to override TargetInstrInfo::getInlineAsmLength method in 13*9880d681SAndroid Build Coastguard Worker // order for MipsLongBranch pass to work correctly when the code has inline 14*9880d681SAndroid Build Coastguard Worker // assembly. The returned value doesn't have to be the asm instruction's exact 15*9880d681SAndroid Build Coastguard Worker // size in bytes; MipsLongBranch only expects it to be the correct upper bound. 16*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_TARGET_MIPS_MIPSINSTRINFO_H 19*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_TARGET_MIPS_MIPSINSTRINFO_H 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker #include "Mips.h" 22*9880d681SAndroid Build Coastguard Worker #include "MipsRegisterInfo.h" 23*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h" 24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h" 25*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h" 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard Worker #define GET_INSTRINFO_HEADER 28*9880d681SAndroid Build Coastguard Worker #include "MipsGenInstrInfo.inc" 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Worker namespace llvm { 31*9880d681SAndroid Build Coastguard Worker class MipsSubtarget; 32*9880d681SAndroid Build Coastguard Worker class MipsInstrInfo : public MipsGenInstrInfo { 33*9880d681SAndroid Build Coastguard Worker virtual void anchor(); 34*9880d681SAndroid Build Coastguard Worker protected: 35*9880d681SAndroid Build Coastguard Worker const MipsSubtarget &Subtarget; 36*9880d681SAndroid Build Coastguard Worker unsigned UncondBrOpc; 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker public: 39*9880d681SAndroid Build Coastguard Worker enum BranchType { 40*9880d681SAndroid Build Coastguard Worker BT_None, // Couldn't analyze branch. 41*9880d681SAndroid Build Coastguard Worker BT_NoBranch, // No branches found. 42*9880d681SAndroid Build Coastguard Worker BT_Uncond, // One unconditional branch. 43*9880d681SAndroid Build Coastguard Worker BT_Cond, // One conditional branch. 44*9880d681SAndroid Build Coastguard Worker BT_CondUncond, // A conditional branch followed by an unconditional branch. 45*9880d681SAndroid Build Coastguard Worker BT_Indirect // One indirct branch. 46*9880d681SAndroid Build Coastguard Worker }; 47*9880d681SAndroid Build Coastguard Worker 48*9880d681SAndroid Build Coastguard Worker explicit MipsInstrInfo(const MipsSubtarget &STI, unsigned UncondBrOpc); 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Worker static const MipsInstrInfo *create(MipsSubtarget &STI); 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Worker /// Branch Analysis 53*9880d681SAndroid Build Coastguard Worker bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 54*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *&FBB, 55*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MachineOperand> &Cond, 56*9880d681SAndroid Build Coastguard Worker bool AllowModify) const override; 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Worker unsigned RemoveBranch(MachineBasicBlock &MBB) const override; 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Worker unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 61*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, 62*9880d681SAndroid Build Coastguard Worker const DebugLoc &DL) const override; 63*9880d681SAndroid Build Coastguard Worker 64*9880d681SAndroid Build Coastguard Worker bool 65*9880d681SAndroid Build Coastguard Worker ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker BranchType analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 68*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *&FBB, 69*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MachineOperand> &Cond, 70*9880d681SAndroid Build Coastguard Worker bool AllowModify, 71*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MachineInstr *> &BranchInstrs) const; 72*9880d681SAndroid Build Coastguard Worker 73*9880d681SAndroid Build Coastguard Worker /// Determine the opcode of a non-delay slot form for a branch if one exists. 74*9880d681SAndroid Build Coastguard Worker unsigned getEquivalentCompactForm(const MachineBasicBlock::iterator I) const; 75*9880d681SAndroid Build Coastguard Worker 76*9880d681SAndroid Build Coastguard Worker /// Predicate to determine if an instruction can go in a forbidden slot. 77*9880d681SAndroid Build Coastguard Worker bool SafeInForbiddenSlot(const MachineInstr &MI) const; 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Worker /// Predicate to determine if an instruction has a forbidden slot. 80*9880d681SAndroid Build Coastguard Worker bool HasForbiddenSlot(const MachineInstr &MI) const; 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Worker /// Insert nop instruction when hazard condition is found 83*9880d681SAndroid Build Coastguard Worker void insertNoop(MachineBasicBlock &MBB, 84*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MI) const override; 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Worker /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As 87*9880d681SAndroid Build Coastguard Worker /// such, whenever a client has an instance of instruction info, it should 88*9880d681SAndroid Build Coastguard Worker /// always be able to get register info as well (through this method). 89*9880d681SAndroid Build Coastguard Worker /// 90*9880d681SAndroid Build Coastguard Worker virtual const MipsRegisterInfo &getRegisterInfo() const = 0; 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker virtual unsigned getOppositeBranchOpc(unsigned Opc) const = 0; 93*9880d681SAndroid Build Coastguard Worker 94*9880d681SAndroid Build Coastguard Worker /// Return the number of bytes of code the specified instruction may be. 95*9880d681SAndroid Build Coastguard Worker unsigned GetInstSizeInBytes(const MachineInstr &MI) const; 96*9880d681SAndroid Build Coastguard Worker storeRegToStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,unsigned SrcReg,bool isKill,int FrameIndex,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI)97*9880d681SAndroid Build Coastguard Worker void storeRegToStackSlot(MachineBasicBlock &MBB, 98*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MBBI, 99*9880d681SAndroid Build Coastguard Worker unsigned SrcReg, bool isKill, int FrameIndex, 100*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC, 101*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI) const override { 102*9880d681SAndroid Build Coastguard Worker storeRegToStack(MBB, MBBI, SrcReg, isKill, FrameIndex, RC, TRI, 0); 103*9880d681SAndroid Build Coastguard Worker } 104*9880d681SAndroid Build Coastguard Worker loadRegFromStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,unsigned DestReg,int FrameIndex,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI)105*9880d681SAndroid Build Coastguard Worker void loadRegFromStackSlot(MachineBasicBlock &MBB, 106*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MBBI, 107*9880d681SAndroid Build Coastguard Worker unsigned DestReg, int FrameIndex, 108*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC, 109*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI) const override { 110*9880d681SAndroid Build Coastguard Worker loadRegFromStack(MBB, MBBI, DestReg, FrameIndex, RC, TRI, 0); 111*9880d681SAndroid Build Coastguard Worker } 112*9880d681SAndroid Build Coastguard Worker 113*9880d681SAndroid Build Coastguard Worker virtual void storeRegToStack(MachineBasicBlock &MBB, 114*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MI, 115*9880d681SAndroid Build Coastguard Worker unsigned SrcReg, bool isKill, int FrameIndex, 116*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC, 117*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI, 118*9880d681SAndroid Build Coastguard Worker int64_t Offset) const = 0; 119*9880d681SAndroid Build Coastguard Worker 120*9880d681SAndroid Build Coastguard Worker virtual void loadRegFromStack(MachineBasicBlock &MBB, 121*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MI, 122*9880d681SAndroid Build Coastguard Worker unsigned DestReg, int FrameIndex, 123*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC, 124*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI, 125*9880d681SAndroid Build Coastguard Worker int64_t Offset) const = 0; 126*9880d681SAndroid Build Coastguard Worker 127*9880d681SAndroid Build Coastguard Worker virtual void adjustStackPtr(unsigned SP, int64_t Amount, 128*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB, 129*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator I) const = 0; 130*9880d681SAndroid Build Coastguard Worker 131*9880d681SAndroid Build Coastguard Worker /// Create an instruction which has the same operands and memory operands 132*9880d681SAndroid Build Coastguard Worker /// as MI but has a new opcode. 133*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder genInstrWithNewOpc(unsigned NewOpc, 134*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator I) const; 135*9880d681SAndroid Build Coastguard Worker 136*9880d681SAndroid Build Coastguard Worker protected: 137*9880d681SAndroid Build Coastguard Worker bool isZeroImm(const MachineOperand &op) const; 138*9880d681SAndroid Build Coastguard Worker 139*9880d681SAndroid Build Coastguard Worker MachineMemOperand *GetMemOperand(MachineBasicBlock &MBB, int FI, 140*9880d681SAndroid Build Coastguard Worker unsigned Flag) const; 141*9880d681SAndroid Build Coastguard Worker 142*9880d681SAndroid Build Coastguard Worker private: 143*9880d681SAndroid Build Coastguard Worker virtual unsigned getAnalyzableBrOpc(unsigned Opc) const = 0; 144*9880d681SAndroid Build Coastguard Worker 145*9880d681SAndroid Build Coastguard Worker void AnalyzeCondBr(const MachineInstr *Inst, unsigned Opc, 146*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *&BB, 147*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MachineOperand> &Cond) const; 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Worker void BuildCondBr(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 150*9880d681SAndroid Build Coastguard Worker const DebugLoc &DL, ArrayRef<MachineOperand> Cond) const; 151*9880d681SAndroid Build Coastguard Worker }; 152*9880d681SAndroid Build Coastguard Worker 153*9880d681SAndroid Build Coastguard Worker /// Create MipsInstrInfo objects. 154*9880d681SAndroid Build Coastguard Worker const MipsInstrInfo *createMips16InstrInfo(const MipsSubtarget &STI); 155*9880d681SAndroid Build Coastguard Worker const MipsInstrInfo *createMipsSEInstrInfo(const MipsSubtarget &STI); 156*9880d681SAndroid Build Coastguard Worker 157*9880d681SAndroid Build Coastguard Worker } 158*9880d681SAndroid Build Coastguard Worker 159*9880d681SAndroid Build Coastguard Worker #endif 160