MipsInstrInfo.cpp revision 5a364c5561ec04e33a6f5d52c14f1bac6f247ea0
1//===-- MipsInstrInfo.cpp - Mips Instruction Information ------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains the Mips implementation of the TargetInstrInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "MipsInstrInfo.h"
15#include "InstPrinter/MipsInstPrinter.h"
16#include "MipsAnalyzeImmediate.h"
17#include "MipsMachineFunction.h"
18#include "MipsTargetMachine.h"
19#include "llvm/ADT/STLExtras.h"
20#include "llvm/CodeGen/MachineInstrBuilder.h"
21#include "llvm/CodeGen/MachineRegisterInfo.h"
22#include "llvm/Support/ErrorHandling.h"
23#include "llvm/Support/TargetRegistry.h"
24
25#define GET_INSTRINFO_CTOR_DTOR
26#include "MipsGenInstrInfo.inc"
27
28using namespace llvm;
29
30// pin vtable to this file
31void MipsInstrInfo::anchor() {}
32
33MipsInstrInfo::MipsInstrInfo(MipsTargetMachine &tm, unsigned UncondBr)
34  : MipsGenInstrInfo(Mips::ADJCALLSTACKDOWN, Mips::ADJCALLSTACKUP),
35    TM(tm), UncondBrOpc(UncondBr) {}
36
37const MipsInstrInfo *MipsInstrInfo::create(MipsTargetMachine &TM) {
38  if (TM.getSubtargetImpl()->inMips16Mode())
39    return llvm::createMips16InstrInfo(TM);
40
41  return llvm::createMipsSEInstrInfo(TM);
42}
43
44bool MipsInstrInfo::isZeroImm(const MachineOperand &op) const {
45  return op.isImm() && op.getImm() == 0;
46}
47
48/// insertNoop - If data hazard condition is found insert the target nop
49/// instruction.
50void MipsInstrInfo::
51insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const
52{
53  DebugLoc DL;
54  BuildMI(MBB, MI, DL, get(Mips::NOP));
55}
56
57MachineMemOperand *MipsInstrInfo::GetMemOperand(MachineBasicBlock &MBB, int FI,
58                                                unsigned Flag) const {
59  MachineFunction &MF = *MBB.getParent();
60  MachineFrameInfo &MFI = *MF.getFrameInfo();
61  unsigned Align = MFI.getObjectAlignment(FI);
62
63  return MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FI), Flag,
64                                 MFI.getObjectSize(FI), Align);
65}
66
67//===----------------------------------------------------------------------===//
68// Branch Analysis
69//===----------------------------------------------------------------------===//
70
71void MipsInstrInfo::AnalyzeCondBr(const MachineInstr *Inst, unsigned Opc,
72                                  MachineBasicBlock *&BB,
73                                  SmallVectorImpl<MachineOperand> &Cond) const {
74  assert(getAnalyzableBrOpc(Opc) && "Not an analyzable branch");
75  int NumOp = Inst->getNumExplicitOperands();
76
77  // for both int and fp branches, the last explicit operand is the
78  // MBB.
79  BB = Inst->getOperand(NumOp-1).getMBB();
80  Cond.push_back(MachineOperand::CreateImm(Opc));
81
82  for (int i=0; i<NumOp-1; i++)
83    Cond.push_back(Inst->getOperand(i));
84}
85
86bool MipsInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
87                                  MachineBasicBlock *&TBB,
88                                  MachineBasicBlock *&FBB,
89                                  SmallVectorImpl<MachineOperand> &Cond,
90                                  bool AllowModify) const {
91  SmallVector<MachineInstr*, 2> BranchInstrs;
92  BranchType BT = AnalyzeBranch(MBB, TBB, FBB, Cond, AllowModify, BranchInstrs);
93
94  return (BT == BT_None) || (BT == BT_Indirect);
95}
96
97void MipsInstrInfo::BuildCondBr(MachineBasicBlock &MBB,
98                                MachineBasicBlock *TBB, DebugLoc DL,
99                                const SmallVectorImpl<MachineOperand>& Cond)
100  const {
101  unsigned Opc = Cond[0].getImm();
102  const MCInstrDesc &MCID = get(Opc);
103  MachineInstrBuilder MIB = BuildMI(&MBB, DL, MCID);
104
105  for (unsigned i = 1; i < Cond.size(); ++i) {
106    if (Cond[i].isReg())
107      MIB.addReg(Cond[i].getReg());
108    else if (Cond[i].isImm())
109      MIB.addImm(Cond[i].getImm());
110    else
111       assert(true && "Cannot copy operand");
112  }
113  MIB.addMBB(TBB);
114}
115
116unsigned MipsInstrInfo::
117InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
118             MachineBasicBlock *FBB,
119             const SmallVectorImpl<MachineOperand> &Cond,
120             DebugLoc DL) const {
121  // Shouldn't be a fall through.
122  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
123
124  // # of condition operands:
125  //  Unconditional branches: 0
126  //  Floating point branches: 1 (opc)
127  //  Int BranchZero: 2 (opc, reg)
128  //  Int Branch: 3 (opc, reg0, reg1)
129  assert((Cond.size() <= 3) &&
130         "# of Mips branch conditions must be <= 3!");
131
132  // Two-way Conditional branch.
133  if (FBB) {
134    BuildCondBr(MBB, TBB, DL, Cond);
135    BuildMI(&MBB, DL, get(UncondBrOpc)).addMBB(FBB);
136    return 2;
137  }
138
139  // One way branch.
140  // Unconditional branch.
141  if (Cond.empty())
142    BuildMI(&MBB, DL, get(UncondBrOpc)).addMBB(TBB);
143  else // Conditional branch.
144    BuildCondBr(MBB, TBB, DL, Cond);
145  return 1;
146}
147
148unsigned MipsInstrInfo::
149RemoveBranch(MachineBasicBlock &MBB) const
150{
151  MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();
152  MachineBasicBlock::reverse_iterator FirstBr;
153  unsigned removed;
154
155  // Skip all the debug instructions.
156  while (I != REnd && I->isDebugValue())
157    ++I;
158
159  FirstBr = I;
160
161  // Up to 2 branches are removed.
162  // Note that indirect branches are not removed.
163  for(removed = 0; I != REnd && removed < 2; ++I, ++removed)
164    if (!getAnalyzableBrOpc(I->getOpcode()))
165      break;
166
167  MBB.erase(I.base(), FirstBr.base());
168
169  return removed;
170}
171
172/// ReverseBranchCondition - Return the inverse opcode of the
173/// specified Branch instruction.
174bool MipsInstrInfo::
175ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
176{
177  assert( (Cond.size() && Cond.size() <= 3) &&
178          "Invalid Mips branch condition!");
179  Cond[0].setImm(getOppositeBranchOpc(Cond[0].getImm()));
180  return false;
181}
182
183MipsInstrInfo::BranchType MipsInstrInfo::
184AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
185              MachineBasicBlock *&FBB, SmallVectorImpl<MachineOperand> &Cond,
186              bool AllowModify,
187              SmallVectorImpl<MachineInstr*> &BranchInstrs) const {
188
189  MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();
190
191  // Skip all the debug instructions.
192  while (I != REnd && I->isDebugValue())
193    ++I;
194
195  if (I == REnd || !isUnpredicatedTerminator(&*I)) {
196    // This block ends with no branches (it just falls through to its succ).
197    // Leave TBB/FBB null.
198    TBB = FBB = NULL;
199    return BT_NoBranch;
200  }
201
202  MachineInstr *LastInst = &*I;
203  unsigned LastOpc = LastInst->getOpcode();
204  BranchInstrs.push_back(LastInst);
205
206  // Not an analyzable branch (e.g., indirect jump).
207  if (!getAnalyzableBrOpc(LastOpc))
208    return LastInst->isIndirectBranch() ? BT_Indirect : BT_None;
209
210  // Get the second to last instruction in the block.
211  unsigned SecondLastOpc = 0;
212  MachineInstr *SecondLastInst = NULL;
213
214  if (++I != REnd) {
215    SecondLastInst = &*I;
216    SecondLastOpc = getAnalyzableBrOpc(SecondLastInst->getOpcode());
217
218    // Not an analyzable branch (must be an indirect jump).
219    if (isUnpredicatedTerminator(SecondLastInst) && !SecondLastOpc)
220      return BT_None;
221  }
222
223  // If there is only one terminator instruction, process it.
224  if (!SecondLastOpc) {
225    // Unconditional branch.
226    if (LastOpc == UncondBrOpc) {
227      TBB = LastInst->getOperand(0).getMBB();
228      return BT_Uncond;
229    }
230
231    // Conditional branch
232    AnalyzeCondBr(LastInst, LastOpc, TBB, Cond);
233    return BT_Cond;
234  }
235
236  // If we reached here, there are two branches.
237  // If there are three terminators, we don't know what sort of block this is.
238  if (++I != REnd && isUnpredicatedTerminator(&*I))
239    return BT_None;
240
241  BranchInstrs.insert(BranchInstrs.begin(), SecondLastInst);
242
243  // If second to last instruction is an unconditional branch,
244  // analyze it and remove the last instruction.
245  if (SecondLastOpc == UncondBrOpc) {
246    // Return if the last instruction cannot be removed.
247    if (!AllowModify)
248      return BT_None;
249
250    TBB = SecondLastInst->getOperand(0).getMBB();
251    LastInst->eraseFromParent();
252    BranchInstrs.pop_back();
253    return BT_Uncond;
254  }
255
256  // Conditional branch followed by an unconditional branch.
257  // The last one must be unconditional.
258  if (LastOpc != UncondBrOpc)
259    return BT_None;
260
261  AnalyzeCondBr(SecondLastInst, SecondLastOpc, TBB, Cond);
262  FBB = LastInst->getOperand(0).getMBB();
263
264  return BT_CondUncond;
265}
266
267/// Return the number of bytes of code the specified instruction may be.
268unsigned MipsInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
269  switch (MI->getOpcode()) {
270  default:
271    return MI->getDesc().getSize();
272  case  TargetOpcode::INLINEASM: {       // Inline Asm: Variable size.
273    const MachineFunction *MF = MI->getParent()->getParent();
274    const char *AsmStr = MI->getOperand(0).getSymbolName();
275    return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
276  }
277  case Mips::CONSTPOOL_ENTRY:
278    // If this machine instr is a constant pool entry, its size is recorded as
279    // operand #2.
280    return MI->getOperand(2).getImm();
281  }
282}
283
284MachineInstrBuilder
285MipsInstrInfo::genInstrWithNewOpc(unsigned NewOpc,
286                                  MachineBasicBlock::iterator I) const {
287  MachineInstrBuilder MIB;
288  MIB = BuildMI(*I->getParent(), I, I->getDebugLoc(), get(NewOpc));
289
290  for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J)
291    MIB.addOperand(I->getOperand(J));
292
293  MIB.setMemRefs(I->memoperands_begin(), I->memoperands_end());
294  return MIB;
295}
296