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