X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FMips%2FMipsInstrInfo.cpp;h=0839147984b5aedc986fb9fbd48563a28bde335a;hb=aecbb87ee8036ba8d2732d5c9fcc2c83a8c8b8d7;hp=06fdb520fc1ea50fc669cf0346dfbc2af9622947;hpb=ff452f53498229668af8e7476efc151c5a227be5;p=oota-llvm.git diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp index 06fdb520fc1..0839147984b 100644 --- a/lib/Target/Mips/MipsInstrInfo.cpp +++ b/lib/Target/Mips/MipsInstrInfo.cpp @@ -1,4 +1,4 @@ -//===- MipsInstrInfo.cpp - Mips Instruction Information ---------*- C++ -*-===// +//===-- MipsInstrInfo.cpp - Mips Instruction Information ------------------===// // // The LLVM Compiler Infrastructure // @@ -12,81 +12,37 @@ //===----------------------------------------------------------------------===// #include "MipsInstrInfo.h" -#include "MipsTargetMachine.h" -#include "MipsMachineFunction.h" #include "InstPrinter/MipsInstPrinter.h" +#include "MipsAnalyzeImmediate.h" +#include "MipsMachineFunction.h" +#include "MipsSubtarget.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" -#include "llvm/ADT/STLExtras.h" - -#define GET_INSTRINFO_CTOR -#include "MipsGenInstrInfo.inc" using namespace llvm; -MipsInstrInfo::MipsInstrInfo(MipsTargetMachine &tm) - : MipsGenInstrInfo(Mips::ADJCALLSTACKDOWN, Mips::ADJCALLSTACKUP), - TM(tm), IsN64(TM.getSubtarget().isABI_N64()), - RI(*TM.getSubtargetImpl(), *this) {} +#define GET_INSTRINFO_CTOR_DTOR +#include "MipsGenInstrInfo.inc" +// Pin the vtable to this file. +void MipsInstrInfo::anchor() {} -const MipsRegisterInfo &MipsInstrInfo::getRegisterInfo() const { - return RI; -} +MipsInstrInfo::MipsInstrInfo(const MipsSubtarget &STI, unsigned UncondBr) + : MipsGenInstrInfo(Mips::ADJCALLSTACKDOWN, Mips::ADJCALLSTACKUP), + Subtarget(STI), UncondBrOpc(UncondBr) {} -static bool isZeroImm(const MachineOperand &op) { - return op.isImm() && op.getImm() == 0; -} +const MipsInstrInfo *MipsInstrInfo::create(MipsSubtarget &STI) { + if (STI.inMips16Mode()) + return llvm::createMips16InstrInfo(STI); -/// isLoadFromStackSlot - If the specified machine instruction is a direct -/// load from a stack slot, return the virtual or physical register number of -/// the destination along with the FrameIndex of the loaded stack slot. If -/// not, return 0. This predicate must return 0 if the instruction has -/// any side effects other than loading from the stack slot. -unsigned MipsInstrInfo:: -isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const -{ - unsigned Opc = MI->getOpcode(); - - if ((Opc == Mips::LW) || (Opc == Mips::LW_P8) || (Opc == Mips::LD) || - (Opc == Mips::LD_P8) || (Opc == Mips::LWC1) || (Opc == Mips::LWC1_P8) || - (Opc == Mips::LDC1) || (Opc == Mips::LDC164) || - (Opc == Mips::LDC164_P8)) { - if ((MI->getOperand(1).isFI()) && // is a stack slot - (MI->getOperand(2).isImm()) && // the imm is zero - (isZeroImm(MI->getOperand(2)))) { - FrameIndex = MI->getOperand(1).getIndex(); - return MI->getOperand(0).getReg(); - } - } - - return 0; + return llvm::createMipsSEInstrInfo(STI); } -/// isStoreToStackSlot - If the specified machine instruction is a direct -/// store to a stack slot, return the virtual or physical register number of -/// the source reg along with the FrameIndex of the loaded stack slot. If -/// not, return 0. This predicate must return 0 if the instruction has -/// any side effects other than storing to the stack slot. -unsigned MipsInstrInfo:: -isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const -{ - unsigned Opc = MI->getOpcode(); - - if ((Opc == Mips::SW) || (Opc == Mips::SW_P8) || (Opc == Mips::SD) || - (Opc == Mips::SD_P8) || (Opc == Mips::SWC1) || (Opc == Mips::SWC1_P8) || - (Opc == Mips::SDC1) || (Opc == Mips::SDC164) || - (Opc == Mips::SDC164_P8)) { - if ((MI->getOperand(1).isFI()) && // is a stack slot - (MI->getOperand(2).isImm()) && // the imm is zero - (isZeroImm(MI->getOperand(2)))) { - FrameIndex = MI->getOperand(1).getIndex(); - return MI->getOperand(0).getReg(); - } - } - return 0; +bool MipsInstrInfo::isZeroImm(const MachineOperand &op) const { + return op.isImm() && op.getImm() == 0; } /// insertNoop - If data hazard condition is found insert the target nop @@ -98,177 +54,26 @@ insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const BuildMI(MBB, MI, DL, get(Mips::NOP)); } -void MipsInstrInfo:: -copyPhysReg(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, DebugLoc DL, - unsigned DestReg, unsigned SrcReg, - bool KillSrc) const { - unsigned Opc = 0, ZeroReg = 0; - - if (Mips::CPURegsRegClass.contains(DestReg)) { // Copy to CPU Reg. - if (Mips::CPURegsRegClass.contains(SrcReg)) - Opc = Mips::ADDu, ZeroReg = Mips::ZERO; - else if (Mips::CCRRegClass.contains(SrcReg)) - Opc = Mips::CFC1; - else if (Mips::FGR32RegClass.contains(SrcReg)) - Opc = Mips::MFC1; - else if (SrcReg == Mips::HI) - Opc = Mips::MFHI, SrcReg = 0; - else if (SrcReg == Mips::LO) - Opc = Mips::MFLO, SrcReg = 0; - } - else if (Mips::CPURegsRegClass.contains(SrcReg)) { // Copy from CPU Reg. - if (Mips::CCRRegClass.contains(DestReg)) - Opc = Mips::CTC1; - else if (Mips::FGR32RegClass.contains(DestReg)) - Opc = Mips::MTC1; - else if (DestReg == Mips::HI) - Opc = Mips::MTHI, DestReg = 0; - else if (DestReg == Mips::LO) - Opc = Mips::MTLO, DestReg = 0; - } - else if (Mips::FGR32RegClass.contains(DestReg, SrcReg)) - Opc = Mips::FMOV_S; - else if (Mips::AFGR64RegClass.contains(DestReg, SrcReg)) - Opc = Mips::FMOV_D32; - else if (Mips::FGR64RegClass.contains(DestReg, SrcReg)) - Opc = Mips::FMOV_D64; - else if (Mips::CCRRegClass.contains(DestReg, SrcReg)) - Opc = Mips::MOVCCRToCCR; - else if (Mips::CPU64RegsRegClass.contains(DestReg)) { // Copy to CPU64 Reg. - if (Mips::CPU64RegsRegClass.contains(SrcReg)) - Opc = Mips::DADDu, ZeroReg = Mips::ZERO_64; - else if (SrcReg == Mips::HI64) - Opc = Mips::MFHI64, SrcReg = 0; - else if (SrcReg == Mips::LO64) - Opc = Mips::MFLO64, SrcReg = 0; - else if (Mips::FGR64RegClass.contains(SrcReg)) - Opc = Mips::DMFC1; - } - else if (Mips::CPU64RegsRegClass.contains(SrcReg)) { // Copy from CPU64 Reg. - if (DestReg == Mips::HI64) - Opc = Mips::MTHI64, DestReg = 0; - else if (DestReg == Mips::LO64) - Opc = Mips::MTLO64, DestReg = 0; - else if (Mips::FGR64RegClass.contains(DestReg)) - Opc = Mips::DMTC1; - } - - assert(Opc && "Cannot copy registers"); - - MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc)); - - if (DestReg) - MIB.addReg(DestReg, RegState::Define); - - if (ZeroReg) - MIB.addReg(ZeroReg); - - if (SrcReg) - MIB.addReg(SrcReg, getKillRegState(KillSrc)); -} - -void MipsInstrInfo:: -storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned SrcReg, bool isKill, int FI, - const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const { - DebugLoc DL; - if (I != MBB.end()) DL = I->getDebugLoc(); - unsigned Opc = 0; - - if (RC == Mips::CPURegsRegisterClass) - Opc = IsN64 ? Mips::SW_P8 : Mips::SW; - else if (RC == Mips::CPU64RegsRegisterClass) - Opc = IsN64 ? Mips::SD_P8 : Mips::SD; - else if (RC == Mips::FGR32RegisterClass) - Opc = IsN64 ? Mips::SWC1_P8 : Mips::SWC1; - else if (RC == Mips::AFGR64RegisterClass) - Opc = Mips::SDC1; - else if (RC == Mips::FGR64RegisterClass) - Opc = IsN64 ? Mips::SDC164_P8 : Mips::SDC164; - - assert(Opc && "Register class not handled!"); - BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)) - .addFrameIndex(FI).addImm(0); -} - -void MipsInstrInfo:: -loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned DestReg, int FI, - const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) const -{ - DebugLoc DL; - if (I != MBB.end()) DL = I->getDebugLoc(); - unsigned Opc = 0; - - if (RC == Mips::CPURegsRegisterClass) - Opc = IsN64 ? Mips::LW_P8 : Mips::LW; - else if (RC == Mips::CPU64RegsRegisterClass) - Opc = IsN64 ? Mips::LD_P8 : Mips::LD; - else if (RC == Mips::FGR32RegisterClass) - Opc = IsN64 ? Mips::LWC1_P8 : Mips::LWC1; - else if (RC == Mips::AFGR64RegisterClass) - Opc = Mips::LDC1; - else if (RC == Mips::FGR64RegisterClass) - Opc = IsN64 ? Mips::LDC164_P8 : Mips::LDC164; - - assert(Opc && "Register class not handled!"); - BuildMI(MBB, I, DL, get(Opc), DestReg).addFrameIndex(FI).addImm(0); -} +MachineMemOperand *MipsInstrInfo::GetMemOperand(MachineBasicBlock &MBB, int FI, + unsigned Flag) const { + MachineFunction &MF = *MBB.getParent(); + MachineFrameInfo &MFI = *MF.getFrameInfo(); + unsigned Align = MFI.getObjectAlignment(FI); -MachineInstr* -MipsInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx, - uint64_t Offset, const MDNode *MDPtr, - DebugLoc DL) const { - MachineInstrBuilder MIB = BuildMI(MF, DL, get(Mips::DBG_VALUE)) - .addFrameIndex(FrameIx).addImm(0).addImm(Offset).addMetadata(MDPtr); - return &*MIB; + return MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI), Flag, + MFI.getObjectSize(FI), Align); } //===----------------------------------------------------------------------===// // Branch Analysis //===----------------------------------------------------------------------===// -static unsigned GetAnalyzableBrOpc(unsigned Opc) { - return (Opc == Mips::BEQ || Opc == Mips::BNE || Opc == Mips::BGTZ || - Opc == Mips::BGEZ || Opc == Mips::BLTZ || Opc == Mips::BLEZ || - Opc == Mips::BEQ64 || Opc == Mips::BNE64 || Opc == Mips::BGTZ64 || - Opc == Mips::BGEZ64 || Opc == Mips::BLTZ64 || Opc == Mips::BLEZ64 || - Opc == Mips::BC1T || Opc == Mips::BC1F || Opc == Mips::B) ? - Opc : 0; -} - -/// GetOppositeBranchOpc - Return the inverse of the specified -/// opcode, e.g. turning BEQ to BNE. -unsigned Mips::GetOppositeBranchOpc(unsigned Opc) -{ - switch (Opc) { - default: llvm_unreachable("Illegal opcode!"); - case Mips::BEQ : return Mips::BNE; - case Mips::BNE : return Mips::BEQ; - case Mips::BGTZ : return Mips::BLEZ; - case Mips::BGEZ : return Mips::BLTZ; - case Mips::BLTZ : return Mips::BGEZ; - case Mips::BLEZ : return Mips::BGTZ; - case Mips::BEQ64 : return Mips::BNE64; - case Mips::BNE64 : return Mips::BEQ64; - case Mips::BGTZ64 : return Mips::BLEZ64; - case Mips::BGEZ64 : return Mips::BLTZ64; - case Mips::BLTZ64 : return Mips::BGEZ64; - case Mips::BLEZ64 : return Mips::BGTZ64; - case Mips::BC1T : return Mips::BC1F; - case Mips::BC1F : return Mips::BC1T; - } -} - -static void AnalyzeCondBr(const MachineInstr* Inst, unsigned Opc, - MachineBasicBlock *&BB, - SmallVectorImpl& Cond) { - assert(GetAnalyzableBrOpc(Opc) && "Not an analyzable branch"); +void MipsInstrInfo::AnalyzeCondBr(const MachineInstr *Inst, unsigned Opc, + MachineBasicBlock *&BB, + SmallVectorImpl &Cond) const { + assert(getAnalyzableBrOpc(Opc) && "Not an analyzable branch"); int NumOp = Inst->getNumExplicitOperands(); - + // for both int and fp branches, the last explicit operand is the // MBB. BB = Inst->getOperand(NumOp-1).getMBB(); @@ -282,101 +87,35 @@ bool MipsInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl &Cond, - bool AllowModify) const -{ - MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend(); - - // Skip all the debug instructions. - while (I != REnd && I->isDebugValue()) - ++I; - - if (I == REnd || !isUnpredicatedTerminator(&*I)) { - // If this block ends with no branches (it just falls through to its succ) - // just return false, leaving TBB/FBB null. - TBB = FBB = NULL; - return false; - } - - MachineInstr *LastInst = &*I; - unsigned LastOpc = LastInst->getOpcode(); - - // Not an analyzable branch (must be an indirect jump). - if (!GetAnalyzableBrOpc(LastOpc)) - return true; - - // Get the second to last instruction in the block. - unsigned SecondLastOpc = 0; - MachineInstr *SecondLastInst = NULL; - - if (++I != REnd) { - SecondLastInst = &*I; - SecondLastOpc = GetAnalyzableBrOpc(SecondLastInst->getOpcode()); - - // Not an analyzable branch (must be an indirect jump). - if (isUnpredicatedTerminator(SecondLastInst) && !SecondLastOpc) - return true; - } - - // If there is only one terminator instruction, process it. - if (!SecondLastOpc) { - // Unconditional branch - if (LastOpc == Mips::B) { - TBB = LastInst->getOperand(0).getMBB(); - return false; - } - - // Conditional branch - AnalyzeCondBr(LastInst, LastOpc, TBB, Cond); - return false; - } + bool AllowModify) const { + SmallVector BranchInstrs; + BranchType BT = AnalyzeBranch(MBB, TBB, FBB, Cond, AllowModify, BranchInstrs); - // If we reached here, there are two branches. - // If there are three terminators, we don't know what sort of block this is. - if (++I != REnd && isUnpredicatedTerminator(&*I)) - return true; - - // If second to last instruction is an unconditional branch, - // analyze it and remove the last instruction. - if (SecondLastOpc == Mips::B) { - // Return if the last instruction cannot be removed. - if (!AllowModify) - return true; - - TBB = SecondLastInst->getOperand(0).getMBB(); - LastInst->eraseFromParent(); - return false; - } - - // Conditional branch followed by an unconditional branch. - // The last one must be unconditional. - if (LastOpc != Mips::B) - return true; - - AnalyzeCondBr(SecondLastInst, SecondLastOpc, TBB, Cond); - FBB = LastInst->getOperand(0).getMBB(); + return (BT == BT_None) || (BT == BT_Indirect); +} - return false; -} - -void MipsInstrInfo::BuildCondBr(MachineBasicBlock &MBB, - MachineBasicBlock *TBB, DebugLoc DL, - const SmallVectorImpl& Cond) - const { +void +MipsInstrInfo::BuildCondBr(MachineBasicBlock &MBB, MachineBasicBlock *TBB, + DebugLoc DL, + const SmallVectorImpl &Cond) const { unsigned Opc = Cond[0].getImm(); const MCInstrDesc &MCID = get(Opc); MachineInstrBuilder MIB = BuildMI(&MBB, DL, MCID); - for (unsigned i = 1; i < Cond.size(); ++i) - MIB.addReg(Cond[i].getReg()); - + for (unsigned i = 1; i < Cond.size(); ++i) { + if (Cond[i].isReg()) + MIB.addReg(Cond[i].getReg()); + else if (Cond[i].isImm()) + MIB.addImm(Cond[i].getImm()); + else + assert(true && "Cannot copy operand"); + } MIB.addMBB(TBB); } -unsigned MipsInstrInfo:: -InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, - MachineBasicBlock *FBB, - const SmallVectorImpl &Cond, - DebugLoc DL) const { +unsigned MipsInstrInfo::InsertBranch( + MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, + const SmallVectorImpl &Cond, DebugLoc DL) const { // Shouldn't be a fall through. assert(TBB && "InsertBranch must not be told to insert a fallthrough"); @@ -391,22 +130,20 @@ InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, // Two-way Conditional branch. if (FBB) { BuildCondBr(MBB, TBB, DL, Cond); - BuildMI(&MBB, DL, get(Mips::B)).addMBB(FBB); + BuildMI(&MBB, DL, get(UncondBrOpc)).addMBB(FBB); return 2; } // One way branch. // Unconditional branch. if (Cond.empty()) - BuildMI(&MBB, DL, get(Mips::B)).addMBB(TBB); + BuildMI(&MBB, DL, get(UncondBrOpc)).addMBB(TBB); else // Conditional branch. BuildCondBr(MBB, TBB, DL, Cond); return 1; } -unsigned MipsInstrInfo:: -RemoveBranch(MachineBasicBlock &MBB) const -{ +unsigned MipsInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend(); MachineBasicBlock::reverse_iterator FirstBr; unsigned removed; @@ -419,8 +156,8 @@ RemoveBranch(MachineBasicBlock &MBB) const // Up to 2 branches are removed. // Note that indirect branches are not removed. - for(removed = 0; I != REnd && removed < 2; ++I, ++removed) - if (!GetAnalyzableBrOpc(I->getOpcode())) + for (removed = 0; I != REnd && removed < 2; ++I, ++removed) + if (!getAnalyzableBrOpc(I->getOpcode())) break; MBB.erase(I.base(), FirstBr.base()); @@ -430,36 +167,123 @@ RemoveBranch(MachineBasicBlock &MBB) const /// ReverseBranchCondition - Return the inverse opcode of the /// specified Branch instruction. -bool MipsInstrInfo:: -ReverseBranchCondition(SmallVectorImpl &Cond) const -{ +bool MipsInstrInfo::ReverseBranchCondition( + SmallVectorImpl &Cond) const { assert( (Cond.size() && Cond.size() <= 3) && "Invalid Mips branch condition!"); - Cond[0].setImm(Mips::GetOppositeBranchOpc(Cond[0].getImm())); + Cond[0].setImm(getOppositeBranchOpc(Cond[0].getImm())); return false; } -/// getGlobalBaseReg - Return a virtual register initialized with the -/// the global base register value. Output instructions required to -/// initialize the register in the function entry block, if necessary. -/// -unsigned MipsInstrInfo::getGlobalBaseReg(MachineFunction *MF) const { - MipsFunctionInfo *MipsFI = MF->getInfo(); - unsigned GlobalBaseReg = MipsFI->getGlobalBaseReg(); - if (GlobalBaseReg != 0) - return GlobalBaseReg; - - // Insert the set of GlobalBaseReg into the first MBB of the function - MachineBasicBlock &FirstMBB = MF->front(); - MachineBasicBlock::iterator MBBI = FirstMBB.begin(); - MachineRegisterInfo &RegInfo = MF->getRegInfo(); - const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); - - GlobalBaseReg = RegInfo.createVirtualRegister(Mips::CPURegsRegisterClass); - BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY), - GlobalBaseReg).addReg(Mips::GP); - RegInfo.addLiveIn(Mips::GP); - - MipsFI->setGlobalBaseReg(GlobalBaseReg); - return GlobalBaseReg; +MipsInstrInfo::BranchType MipsInstrInfo::AnalyzeBranch( + MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, + SmallVectorImpl &Cond, bool AllowModify, + SmallVectorImpl &BranchInstrs) const { + + MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend(); + + // Skip all the debug instructions. + while (I != REnd && I->isDebugValue()) + ++I; + + if (I == REnd || !isUnpredicatedTerminator(&*I)) { + // This block ends with no branches (it just falls through to its succ). + // Leave TBB/FBB null. + TBB = FBB = nullptr; + return BT_NoBranch; + } + + MachineInstr *LastInst = &*I; + unsigned LastOpc = LastInst->getOpcode(); + BranchInstrs.push_back(LastInst); + + // Not an analyzable branch (e.g., indirect jump). + if (!getAnalyzableBrOpc(LastOpc)) + return LastInst->isIndirectBranch() ? BT_Indirect : BT_None; + + // Get the second to last instruction in the block. + unsigned SecondLastOpc = 0; + MachineInstr *SecondLastInst = nullptr; + + if (++I != REnd) { + SecondLastInst = &*I; + SecondLastOpc = getAnalyzableBrOpc(SecondLastInst->getOpcode()); + + // Not an analyzable branch (must be an indirect jump). + if (isUnpredicatedTerminator(SecondLastInst) && !SecondLastOpc) + return BT_None; + } + + // If there is only one terminator instruction, process it. + if (!SecondLastOpc) { + // Unconditional branch. + if (LastOpc == UncondBrOpc) { + TBB = LastInst->getOperand(0).getMBB(); + return BT_Uncond; + } + + // Conditional branch + AnalyzeCondBr(LastInst, LastOpc, TBB, Cond); + return BT_Cond; + } + + // If we reached here, there are two branches. + // If there are three terminators, we don't know what sort of block this is. + if (++I != REnd && isUnpredicatedTerminator(&*I)) + return BT_None; + + BranchInstrs.insert(BranchInstrs.begin(), SecondLastInst); + + // If second to last instruction is an unconditional branch, + // analyze it and remove the last instruction. + if (SecondLastOpc == UncondBrOpc) { + // Return if the last instruction cannot be removed. + if (!AllowModify) + return BT_None; + + TBB = SecondLastInst->getOperand(0).getMBB(); + LastInst->eraseFromParent(); + BranchInstrs.pop_back(); + return BT_Uncond; + } + + // Conditional branch followed by an unconditional branch. + // The last one must be unconditional. + if (LastOpc != UncondBrOpc) + return BT_None; + + AnalyzeCondBr(SecondLastInst, SecondLastOpc, TBB, Cond); + FBB = LastInst->getOperand(0).getMBB(); + + return BT_CondUncond; +} + +/// Return the number of bytes of code the specified instruction may be. +unsigned MipsInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { + switch (MI->getOpcode()) { + default: + return MI->getDesc().getSize(); + case TargetOpcode::INLINEASM: { // Inline Asm: Variable size. + const MachineFunction *MF = MI->getParent()->getParent(); + const char *AsmStr = MI->getOperand(0).getSymbolName(); + return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo()); + } + case Mips::CONSTPOOL_ENTRY: + // If this machine instr is a constant pool entry, its size is recorded as + // operand #2. + return MI->getOperand(2).getImm(); + } +} + +MachineInstrBuilder +MipsInstrInfo::genInstrWithNewOpc(unsigned NewOpc, + MachineBasicBlock::iterator I) const { + MachineInstrBuilder MIB; + MIB = BuildMI(*I->getParent(), I, I->getDebugLoc(), get(NewOpc)); + + for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) + MIB.addOperand(I->getOperand(J)); + + MIB.setMemRefs(I->memoperands_begin(), I->memoperands_end()); + return MIB; }