MipsInstrInfo.cpp revision 243830
133965Sjdp//===-- MipsInstrInfo.cpp - Mips Instruction Information ------------------===// 233965Sjdp// 333965Sjdp// The LLVM Compiler Infrastructure 433965Sjdp// 533965Sjdp// This file is distributed under the University of Illinois Open Source 633965Sjdp// License. See LICENSE.TXT for details. 733965Sjdp// 833965Sjdp//===----------------------------------------------------------------------===// 933965Sjdp// 1033965Sjdp// This file contains the Mips implementation of the TargetInstrInfo class. 1133965Sjdp// 1233965Sjdp//===----------------------------------------------------------------------===// 1333965Sjdp 1433965Sjdp#include "MipsAnalyzeImmediate.h" 1533965Sjdp#include "MipsInstrInfo.h" 1633965Sjdp#include "MipsTargetMachine.h" 1733965Sjdp#include "MipsMachineFunction.h" 1833965Sjdp#include "InstPrinter/MipsInstPrinter.h" 1933965Sjdp#include "llvm/CodeGen/MachineInstrBuilder.h" 2033965Sjdp#include "llvm/CodeGen/MachineRegisterInfo.h" 2133965Sjdp#include "llvm/Support/ErrorHandling.h" 2233965Sjdp#include "llvm/Support/TargetRegistry.h" 2333965Sjdp#include "llvm/ADT/STLExtras.h" 2433965Sjdp 2533965Sjdp#define GET_INSTRINFO_CTOR 2633965Sjdp#include "MipsGenInstrInfo.inc" 2733965Sjdp 2833965Sjdpusing namespace llvm; 2933965Sjdp 3033965SjdpMipsInstrInfo::MipsInstrInfo(MipsTargetMachine &tm, unsigned UncondBr) 3133965Sjdp : MipsGenInstrInfo(Mips::ADJCALLSTACKDOWN, Mips::ADJCALLSTACKUP), 3233965Sjdp TM(tm), UncondBrOpc(UncondBr) {} 3333965Sjdp 3433965Sjdpconst MipsInstrInfo *MipsInstrInfo::create(MipsTargetMachine &TM) { 3533965Sjdp if (TM.getSubtargetImpl()->inMips16Mode()) 3633965Sjdp return llvm::createMips16InstrInfo(TM); 3733965Sjdp 3833965Sjdp return llvm::createMipsSEInstrInfo(TM); 3933965Sjdp} 4033965Sjdp 4133965Sjdpbool MipsInstrInfo::isZeroImm(const MachineOperand &op) const { 4233965Sjdp return op.isImm() && op.getImm() == 0; 4333965Sjdp} 4433965Sjdp 4533965Sjdp/// insertNoop - If data hazard condition is found insert the target nop 4633965Sjdp/// instruction. 4733965Sjdpvoid MipsInstrInfo:: 4833965SjdpinsertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const 4933965Sjdp{ 5033965Sjdp DebugLoc DL; 5133965Sjdp BuildMI(MBB, MI, DL, get(Mips::NOP)); 5233965Sjdp} 5333965Sjdp 5433965SjdpMachineMemOperand *MipsInstrInfo::GetMemOperand(MachineBasicBlock &MBB, int FI, 5533965Sjdp unsigned Flag) const { 5633965Sjdp MachineFunction &MF = *MBB.getParent(); 5733965Sjdp MachineFrameInfo &MFI = *MF.getFrameInfo(); 5833965Sjdp unsigned Align = MFI.getObjectAlignment(FI); 5933965Sjdp 6033965Sjdp return MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI), Flag, 6133965Sjdp MFI.getObjectSize(FI), Align); 6233965Sjdp} 6333965Sjdp 6433965SjdpMachineInstr* 6533965SjdpMipsInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx, 6633965Sjdp uint64_t Offset, const MDNode *MDPtr, 6733965Sjdp DebugLoc DL) const { 6833965Sjdp MachineInstrBuilder MIB = BuildMI(MF, DL, get(Mips::DBG_VALUE)) 6933965Sjdp .addFrameIndex(FrameIx).addImm(0).addImm(Offset).addMetadata(MDPtr); 7033965Sjdp return &*MIB; 7133965Sjdp} 7233965Sjdp 7333965Sjdp//===----------------------------------------------------------------------===// 7433965Sjdp// Branch Analysis 7533965Sjdp//===----------------------------------------------------------------------===// 7633965Sjdp 7733965Sjdpvoid MipsInstrInfo::AnalyzeCondBr(const MachineInstr *Inst, unsigned Opc, 7833965Sjdp MachineBasicBlock *&BB, 7933965Sjdp SmallVectorImpl<MachineOperand> &Cond) const { 8033965Sjdp assert(GetAnalyzableBrOpc(Opc) && "Not an analyzable branch"); 8133965Sjdp int NumOp = Inst->getNumExplicitOperands(); 8233965Sjdp 8333965Sjdp // for both int and fp branches, the last explicit operand is the 8433965Sjdp // MBB. 8533965Sjdp BB = Inst->getOperand(NumOp-1).getMBB(); 8633965Sjdp Cond.push_back(MachineOperand::CreateImm(Opc)); 8733965Sjdp 8833965Sjdp for (int i=0; i<NumOp-1; i++) 8933965Sjdp Cond.push_back(Inst->getOperand(i)); 9033965Sjdp} 9133965Sjdp 9233965Sjdpbool MipsInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 9333965Sjdp MachineBasicBlock *&TBB, 9433965Sjdp MachineBasicBlock *&FBB, 9533965Sjdp SmallVectorImpl<MachineOperand> &Cond, 9633965Sjdp bool AllowModify) const 9733965Sjdp{ 9833965Sjdp 9933965Sjdp MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend(); 10033965Sjdp 10133965Sjdp // Skip all the debug instructions. 10233965Sjdp while (I != REnd && I->isDebugValue()) 10333965Sjdp ++I; 10433965Sjdp 10533965Sjdp if (I == REnd || !isUnpredicatedTerminator(&*I)) { 10633965Sjdp // If this block ends with no branches (it just falls through to its succ) 10733965Sjdp // just return false, leaving TBB/FBB null. 10833965Sjdp TBB = FBB = NULL; 10933965Sjdp return false; 11033965Sjdp } 11133965Sjdp 11233965Sjdp MachineInstr *LastInst = &*I; 11333965Sjdp unsigned LastOpc = LastInst->getOpcode(); 11433965Sjdp 11533965Sjdp // Not an analyzable branch (must be an indirect jump). 11633965Sjdp if (!GetAnalyzableBrOpc(LastOpc)) 11733965Sjdp return true; 11833965Sjdp 11933965Sjdp // Get the second to last instruction in the block. 12033965Sjdp unsigned SecondLastOpc = 0; 12133965Sjdp MachineInstr *SecondLastInst = NULL; 12233965Sjdp 12333965Sjdp if (++I != REnd) { 12433965Sjdp SecondLastInst = &*I; 12533965Sjdp SecondLastOpc = GetAnalyzableBrOpc(SecondLastInst->getOpcode()); 12633965Sjdp 12733965Sjdp // Not an analyzable branch (must be an indirect jump). 12833965Sjdp if (isUnpredicatedTerminator(SecondLastInst) && !SecondLastOpc) 12933965Sjdp return true; 13033965Sjdp } 13133965Sjdp 13233965Sjdp // If there is only one terminator instruction, process it. 13333965Sjdp if (!SecondLastOpc) { 13433965Sjdp // Unconditional branch 13533965Sjdp if (LastOpc == UncondBrOpc) { 13633965Sjdp TBB = LastInst->getOperand(0).getMBB(); 13733965Sjdp return false; 13833965Sjdp } 13933965Sjdp 14033965Sjdp // Conditional branch 14133965Sjdp AnalyzeCondBr(LastInst, LastOpc, TBB, Cond); 14233965Sjdp return false; 14333965Sjdp } 14433965Sjdp 14533965Sjdp // If we reached here, there are two branches. 14633965Sjdp // If there are three terminators, we don't know what sort of block this is. 14733965Sjdp if (++I != REnd && isUnpredicatedTerminator(&*I)) 14833965Sjdp return true; 14933965Sjdp 15033965Sjdp // If second to last instruction is an unconditional branch, 15133965Sjdp // analyze it and remove the last instruction. 15233965Sjdp if (SecondLastOpc == UncondBrOpc) { 15333965Sjdp // Return if the last instruction cannot be removed. 15433965Sjdp if (!AllowModify) 15533965Sjdp return true; 15633965Sjdp 15733965Sjdp TBB = SecondLastInst->getOperand(0).getMBB(); 15833965Sjdp LastInst->eraseFromParent(); 15933965Sjdp return false; 16033965Sjdp } 16133965Sjdp 16233965Sjdp // Conditional branch followed by an unconditional branch. 16333965Sjdp // The last one must be unconditional. 16433965Sjdp if (LastOpc != UncondBrOpc) 16533965Sjdp return true; 16633965Sjdp 16733965Sjdp AnalyzeCondBr(SecondLastInst, SecondLastOpc, TBB, Cond); 16833965Sjdp FBB = LastInst->getOperand(0).getMBB(); 16933965Sjdp 17033965Sjdp return false; 17133965Sjdp} 17233965Sjdp 17333965Sjdpvoid MipsInstrInfo::BuildCondBr(MachineBasicBlock &MBB, 17433965Sjdp MachineBasicBlock *TBB, DebugLoc DL, 17533965Sjdp const SmallVectorImpl<MachineOperand>& Cond) 17633965Sjdp const { 17733965Sjdp unsigned Opc = Cond[0].getImm(); 17833965Sjdp const MCInstrDesc &MCID = get(Opc); 17933965Sjdp MachineInstrBuilder MIB = BuildMI(&MBB, DL, MCID); 18033965Sjdp 18133965Sjdp for (unsigned i = 1; i < Cond.size(); ++i) { 18233965Sjdp if (Cond[i].isReg()) 18333965Sjdp MIB.addReg(Cond[i].getReg()); 18433965Sjdp else if (Cond[i].isImm()) 18533965Sjdp MIB.addImm(Cond[i].getImm()); 18633965Sjdp else 18733965Sjdp assert(true && "Cannot copy operand"); 18833965Sjdp } 18933965Sjdp MIB.addMBB(TBB); 19033965Sjdp} 19133965Sjdp 19233965Sjdpunsigned MipsInstrInfo:: 19333965SjdpInsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 19433965Sjdp MachineBasicBlock *FBB, 19533965Sjdp const SmallVectorImpl<MachineOperand> &Cond, 19633965Sjdp DebugLoc DL) const { 19733965Sjdp // Shouldn't be a fall through. 19833965Sjdp assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 19933965Sjdp 20033965Sjdp // # of condition operands: 20133965Sjdp // Unconditional branches: 0 20233965Sjdp // Floating point branches: 1 (opc) 20333965Sjdp // Int BranchZero: 2 (opc, reg) 20433965Sjdp // Int Branch: 3 (opc, reg0, reg1) 20533965Sjdp assert((Cond.size() <= 3) && 20633965Sjdp "# of Mips branch conditions must be <= 3!"); 20733965Sjdp 20833965Sjdp // Two-way Conditional branch. 20933965Sjdp if (FBB) { 21033965Sjdp BuildCondBr(MBB, TBB, DL, Cond); 21133965Sjdp BuildMI(&MBB, DL, get(UncondBrOpc)).addMBB(FBB); 21233965Sjdp return 2; 21333965Sjdp } 21433965Sjdp 21533965Sjdp // One way branch. 21633965Sjdp // Unconditional branch. 21733965Sjdp if (Cond.empty()) 21833965Sjdp BuildMI(&MBB, DL, get(UncondBrOpc)).addMBB(TBB); 21933965Sjdp else // Conditional branch. 22033965Sjdp BuildCondBr(MBB, TBB, DL, Cond); 22133965Sjdp return 1; 22233965Sjdp} 22333965Sjdp 22433965Sjdpunsigned MipsInstrInfo:: 22533965SjdpRemoveBranch(MachineBasicBlock &MBB) const 22633965Sjdp{ 22733965Sjdp MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend(); 22833965Sjdp MachineBasicBlock::reverse_iterator FirstBr; 22933965Sjdp unsigned removed; 23033965Sjdp 23133965Sjdp // Skip all the debug instructions. 23233965Sjdp while (I != REnd && I->isDebugValue()) 23333965Sjdp ++I; 23433965Sjdp 23533965Sjdp FirstBr = I; 23633965Sjdp 23733965Sjdp // Up to 2 branches are removed. 23833965Sjdp // Note that indirect branches are not removed. 23933965Sjdp for(removed = 0; I != REnd && removed < 2; ++I, ++removed) 24033965Sjdp if (!GetAnalyzableBrOpc(I->getOpcode())) 24133965Sjdp break; 24233965Sjdp 24333965Sjdp MBB.erase(I.base(), FirstBr.base()); 24433965Sjdp 24533965Sjdp return removed; 24633965Sjdp} 24733965Sjdp 24833965Sjdp/// ReverseBranchCondition - Return the inverse opcode of the 24933965Sjdp/// specified Branch instruction. 25033965Sjdpbool MipsInstrInfo:: 25133965SjdpReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const 25233965Sjdp{ 25333965Sjdp assert( (Cond.size() && Cond.size() <= 3) && 25433965Sjdp "Invalid Mips branch condition!"); 25533965Sjdp Cond[0].setImm(GetOppositeBranchOpc(Cond[0].getImm())); 25633965Sjdp return false; 25733965Sjdp} 25833965Sjdp 25933965Sjdp/// Return the number of bytes of code the specified instruction may be. 26033965Sjdpunsigned MipsInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { 26133965Sjdp switch (MI->getOpcode()) { 26233965Sjdp default: 26333965Sjdp return MI->getDesc().getSize(); 26433965Sjdp case TargetOpcode::INLINEASM: { // Inline Asm: Variable size. 26533965Sjdp const MachineFunction *MF = MI->getParent()->getParent(); 26633965Sjdp const char *AsmStr = MI->getOperand(0).getSymbolName(); 26733965Sjdp return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo()); 26833965Sjdp } 26933965Sjdp } 27033965Sjdp} 27133965Sjdp