MipsInstrInfo.cpp revision 193323
1193323Sed//===- MipsInstrInfo.cpp - Mips Instruction Information ---------*- C++ -*-===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file contains the Mips implementation of the TargetInstrInfo class.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14193323Sed#include "MipsInstrInfo.h"
15193323Sed#include "MipsTargetMachine.h"
16193323Sed#include "llvm/ADT/STLExtras.h"
17193323Sed#include "llvm/CodeGen/MachineInstrBuilder.h"
18193323Sed#include "MipsGenInstrInfo.inc"
19193323Sed
20193323Sedusing namespace llvm;
21193323Sed
22193323SedMipsInstrInfo::MipsInstrInfo(MipsTargetMachine &tm)
23193323Sed  : TargetInstrInfoImpl(MipsInsts, array_lengthof(MipsInsts)),
24193323Sed    TM(tm), RI(*TM.getSubtargetImpl(), *this) {}
25193323Sed
26193323Sedstatic bool isZeroImm(const MachineOperand &op) {
27193323Sed  return op.isImm() && op.getImm() == 0;
28193323Sed}
29193323Sed
30193323Sed/// Return true if the instruction is a register to register move and
31193323Sed/// leave the source and dest operands in the passed parameters.
32193323Sedbool MipsInstrInfo::
33193323SedisMoveInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg,
34193323Sed            unsigned &SrcSubIdx, unsigned &DstSubIdx) const
35193323Sed{
36193323Sed  SrcSubIdx = DstSubIdx = 0; // No sub-registers.
37193323Sed
38193323Sed  // addu $dst, $src, $zero || addu $dst, $zero, $src
39193323Sed  // or   $dst, $src, $zero || or   $dst, $zero, $src
40193323Sed  if ((MI.getOpcode() == Mips::ADDu) || (MI.getOpcode() == Mips::OR)) {
41193323Sed    if (MI.getOperand(1).getReg() == Mips::ZERO) {
42193323Sed      DstReg = MI.getOperand(0).getReg();
43193323Sed      SrcReg = MI.getOperand(2).getReg();
44193323Sed      return true;
45193323Sed    } else if (MI.getOperand(2).getReg() == Mips::ZERO) {
46193323Sed      DstReg = MI.getOperand(0).getReg();
47193323Sed      SrcReg = MI.getOperand(1).getReg();
48193323Sed      return true;
49193323Sed    }
50193323Sed  }
51193323Sed
52193323Sed  // mov $fpDst, $fpSrc
53193323Sed  // mfc $gpDst, $fpSrc
54193323Sed  // mtc $fpDst, $gpSrc
55193323Sed  if (MI.getOpcode() == Mips::FMOV_S32 ||
56193323Sed      MI.getOpcode() == Mips::FMOV_D32 ||
57193323Sed      MI.getOpcode() == Mips::MFC1 ||
58193323Sed      MI.getOpcode() == Mips::MTC1 ||
59193323Sed      MI.getOpcode() == Mips::MOVCCRToCCR) {
60193323Sed    DstReg = MI.getOperand(0).getReg();
61193323Sed    SrcReg = MI.getOperand(1).getReg();
62193323Sed    return true;
63193323Sed  }
64193323Sed
65193323Sed  // addiu $dst, $src, 0
66193323Sed  if (MI.getOpcode() == Mips::ADDiu) {
67193323Sed    if ((MI.getOperand(1).isReg()) && (isZeroImm(MI.getOperand(2)))) {
68193323Sed      DstReg = MI.getOperand(0).getReg();
69193323Sed      SrcReg = MI.getOperand(1).getReg();
70193323Sed      return true;
71193323Sed    }
72193323Sed  }
73193323Sed
74193323Sed  return false;
75193323Sed}
76193323Sed
77193323Sed/// isLoadFromStackSlot - If the specified machine instruction is a direct
78193323Sed/// load from a stack slot, return the virtual or physical register number of
79193323Sed/// the destination along with the FrameIndex of the loaded stack slot.  If
80193323Sed/// not, return 0.  This predicate must return 0 if the instruction has
81193323Sed/// any side effects other than loading from the stack slot.
82193323Sedunsigned MipsInstrInfo::
83193323SedisLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const
84193323Sed{
85193323Sed  if ((MI->getOpcode() == Mips::LW) || (MI->getOpcode() == Mips::LWC1) ||
86193323Sed      (MI->getOpcode() == Mips::LDC1)) {
87193323Sed    if ((MI->getOperand(2).isFI()) && // is a stack slot
88193323Sed        (MI->getOperand(1).isImm()) &&  // the imm is zero
89193323Sed        (isZeroImm(MI->getOperand(1)))) {
90193323Sed      FrameIndex = MI->getOperand(2).getIndex();
91193323Sed      return MI->getOperand(0).getReg();
92193323Sed    }
93193323Sed  }
94193323Sed
95193323Sed  return 0;
96193323Sed}
97193323Sed
98193323Sed/// isStoreToStackSlot - If the specified machine instruction is a direct
99193323Sed/// store to a stack slot, return the virtual or physical register number of
100193323Sed/// the source reg along with the FrameIndex of the loaded stack slot.  If
101193323Sed/// not, return 0.  This predicate must return 0 if the instruction has
102193323Sed/// any side effects other than storing to the stack slot.
103193323Sedunsigned MipsInstrInfo::
104193323SedisStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const
105193323Sed{
106193323Sed  if ((MI->getOpcode() == Mips::SW) || (MI->getOpcode() == Mips::SWC1) ||
107193323Sed      (MI->getOpcode() == Mips::SDC1)) {
108193323Sed    if ((MI->getOperand(2).isFI()) && // is a stack slot
109193323Sed        (MI->getOperand(1).isImm()) &&  // the imm is zero
110193323Sed        (isZeroImm(MI->getOperand(1)))) {
111193323Sed      FrameIndex = MI->getOperand(2).getIndex();
112193323Sed      return MI->getOperand(0).getReg();
113193323Sed    }
114193323Sed  }
115193323Sed  return 0;
116193323Sed}
117193323Sed
118193323Sed/// insertNoop - If data hazard condition is found insert the target nop
119193323Sed/// instruction.
120193323Sedvoid MipsInstrInfo::
121193323SedinsertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const
122193323Sed{
123193323Sed  DebugLoc DL = DebugLoc::getUnknownLoc();
124193323Sed  if (MI != MBB.end()) DL = MI->getDebugLoc();
125193323Sed  BuildMI(MBB, MI, DL, get(Mips::NOP));
126193323Sed}
127193323Sed
128193323Sedbool MipsInstrInfo::
129193323SedcopyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
130193323Sed             unsigned DestReg, unsigned SrcReg,
131193323Sed             const TargetRegisterClass *DestRC,
132193323Sed             const TargetRegisterClass *SrcRC) const {
133193323Sed  DebugLoc DL = DebugLoc::getUnknownLoc();
134193323Sed  if (I != MBB.end()) DL = I->getDebugLoc();
135193323Sed
136193323Sed  if (DestRC != SrcRC) {
137193323Sed
138193323Sed    // Copy to/from FCR31 condition register
139193323Sed    if ((DestRC == Mips::CPURegsRegisterClass) &&
140193323Sed        (SrcRC == Mips::CCRRegisterClass))
141193323Sed      BuildMI(MBB, I, DL, get(Mips::CFC1), DestReg).addReg(SrcReg);
142193323Sed    else if ((DestRC == Mips::CCRRegisterClass) &&
143193323Sed        (SrcRC == Mips::CPURegsRegisterClass))
144193323Sed      BuildMI(MBB, I, DL, get(Mips::CTC1), DestReg).addReg(SrcReg);
145193323Sed
146193323Sed    // Moves between coprocessors and cpu
147193323Sed    else if ((DestRC == Mips::CPURegsRegisterClass) &&
148193323Sed        (SrcRC == Mips::FGR32RegisterClass))
149193323Sed      BuildMI(MBB, I, DL, get(Mips::MFC1), DestReg).addReg(SrcReg);
150193323Sed    else if ((DestRC == Mips::FGR32RegisterClass) &&
151193323Sed             (SrcRC == Mips::CPURegsRegisterClass))
152193323Sed      BuildMI(MBB, I, DL, get(Mips::MTC1), DestReg).addReg(SrcReg);
153193323Sed
154193323Sed    // Move from/to Hi/Lo registers
155193323Sed    else if ((DestRC == Mips::HILORegisterClass) &&
156193323Sed             (SrcRC == Mips::CPURegsRegisterClass)) {
157193323Sed      unsigned Opc = (DestReg == Mips::HI) ? Mips::MTHI : Mips::MTLO;
158193323Sed      BuildMI(MBB, I, DL, get(Opc), DestReg);
159193323Sed    } else if ((SrcRC == Mips::HILORegisterClass) &&
160193323Sed               (DestRC == Mips::CPURegsRegisterClass)) {
161193323Sed      unsigned Opc = (SrcReg == Mips::HI) ? Mips::MFHI : Mips::MFLO;
162193323Sed      BuildMI(MBB, I, DL, get(Opc), DestReg);
163193323Sed
164193323Sed    // Can't copy this register
165193323Sed    } else
166193323Sed      return false;
167193323Sed
168193323Sed    return true;
169193323Sed  }
170193323Sed
171193323Sed  if (DestRC == Mips::CPURegsRegisterClass)
172193323Sed    BuildMI(MBB, I, DL, get(Mips::ADDu), DestReg).addReg(Mips::ZERO)
173193323Sed      .addReg(SrcReg);
174193323Sed  else if (DestRC == Mips::FGR32RegisterClass)
175193323Sed    BuildMI(MBB, I, DL, get(Mips::FMOV_S32), DestReg).addReg(SrcReg);
176193323Sed  else if (DestRC == Mips::AFGR64RegisterClass)
177193323Sed    BuildMI(MBB, I, DL, get(Mips::FMOV_D32), DestReg).addReg(SrcReg);
178193323Sed  else if (DestRC == Mips::CCRRegisterClass)
179193323Sed    BuildMI(MBB, I, DL, get(Mips::MOVCCRToCCR), DestReg).addReg(SrcReg);
180193323Sed  else
181193323Sed    // Can't copy this register
182193323Sed    return false;
183193323Sed
184193323Sed  return true;
185193323Sed}
186193323Sed
187193323Sedvoid MipsInstrInfo::
188193323SedstoreRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
189193323Sed                    unsigned SrcReg, bool isKill, int FI,
190193323Sed                    const TargetRegisterClass *RC) const {
191193323Sed  unsigned Opc;
192193323Sed
193193323Sed  DebugLoc DL = DebugLoc::getUnknownLoc();
194193323Sed  if (I != MBB.end()) DL = I->getDebugLoc();
195193323Sed
196193323Sed  if (RC == Mips::CPURegsRegisterClass)
197193323Sed    Opc = Mips::SW;
198193323Sed  else if (RC == Mips::FGR32RegisterClass)
199193323Sed    Opc = Mips::SWC1;
200193323Sed  else {
201193323Sed    assert(RC == Mips::AFGR64RegisterClass);
202193323Sed    Opc = Mips::SDC1;
203193323Sed  }
204193323Sed
205193323Sed  BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill))
206193323Sed          .addImm(0).addFrameIndex(FI);
207193323Sed}
208193323Sed
209193323Sedvoid MipsInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
210193323Sed  bool isKill, SmallVectorImpl<MachineOperand> &Addr,
211193323Sed  const TargetRegisterClass *RC, SmallVectorImpl<MachineInstr*> &NewMIs) const
212193323Sed{
213193323Sed  unsigned Opc;
214193323Sed  if (RC == Mips::CPURegsRegisterClass)
215193323Sed    Opc = Mips::SW;
216193323Sed  else if (RC == Mips::FGR32RegisterClass)
217193323Sed    Opc = Mips::SWC1;
218193323Sed  else {
219193323Sed    assert(RC == Mips::AFGR64RegisterClass);
220193323Sed    Opc = Mips::SDC1;
221193323Sed  }
222193323Sed
223193323Sed  DebugLoc DL = DebugLoc::getUnknownLoc();
224193323Sed  MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc))
225193323Sed    .addReg(SrcReg, getKillRegState(isKill));
226193323Sed  for (unsigned i = 0, e = Addr.size(); i != e; ++i)
227193323Sed    MIB.addOperand(Addr[i]);
228193323Sed  NewMIs.push_back(MIB);
229193323Sed  return;
230193323Sed}
231193323Sed
232193323Sedvoid MipsInstrInfo::
233193323SedloadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
234193323Sed                     unsigned DestReg, int FI,
235193323Sed                     const TargetRegisterClass *RC) const
236193323Sed{
237193323Sed  unsigned Opc;
238193323Sed  if (RC == Mips::CPURegsRegisterClass)
239193323Sed    Opc = Mips::LW;
240193323Sed  else if (RC == Mips::FGR32RegisterClass)
241193323Sed    Opc = Mips::LWC1;
242193323Sed  else {
243193323Sed    assert(RC == Mips::AFGR64RegisterClass);
244193323Sed    Opc = Mips::LDC1;
245193323Sed  }
246193323Sed
247193323Sed  DebugLoc DL = DebugLoc::getUnknownLoc();
248193323Sed  if (I != MBB.end()) DL = I->getDebugLoc();
249193323Sed  BuildMI(MBB, I, DL, get(Opc), DestReg).addImm(0).addFrameIndex(FI);
250193323Sed}
251193323Sed
252193323Sedvoid MipsInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
253193323Sed                                    SmallVectorImpl<MachineOperand> &Addr,
254193323Sed                                    const TargetRegisterClass *RC,
255193323Sed                                 SmallVectorImpl<MachineInstr*> &NewMIs) const {
256193323Sed  unsigned Opc;
257193323Sed  if (RC == Mips::CPURegsRegisterClass)
258193323Sed    Opc = Mips::LW;
259193323Sed  else if (RC == Mips::FGR32RegisterClass)
260193323Sed    Opc = Mips::LWC1;
261193323Sed  else {
262193323Sed    assert(RC == Mips::AFGR64RegisterClass);
263193323Sed    Opc = Mips::LDC1;
264193323Sed  }
265193323Sed
266193323Sed  DebugLoc DL = DebugLoc::getUnknownLoc();
267193323Sed  MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg);
268193323Sed  for (unsigned i = 0, e = Addr.size(); i != e; ++i)
269193323Sed    MIB.addOperand(Addr[i]);
270193323Sed  NewMIs.push_back(MIB);
271193323Sed  return;
272193323Sed}
273193323Sed
274193323SedMachineInstr *MipsInstrInfo::
275193323SedfoldMemoryOperandImpl(MachineFunction &MF,
276193323Sed                      MachineInstr* MI,
277193323Sed                      const SmallVectorImpl<unsigned> &Ops, int FI) const
278193323Sed{
279193323Sed  if (Ops.size() != 1) return NULL;
280193323Sed
281193323Sed  MachineInstr *NewMI = NULL;
282193323Sed
283193323Sed  switch (MI->getOpcode()) {
284193323Sed  case Mips::ADDu:
285193323Sed    if ((MI->getOperand(0).isReg()) &&
286193323Sed        (MI->getOperand(1).isReg()) &&
287193323Sed        (MI->getOperand(1).getReg() == Mips::ZERO) &&
288193323Sed        (MI->getOperand(2).isReg())) {
289193323Sed      if (Ops[0] == 0) {    // COPY -> STORE
290193323Sed        unsigned SrcReg = MI->getOperand(2).getReg();
291193323Sed        bool isKill = MI->getOperand(2).isKill();
292193323Sed        NewMI = BuildMI(MF, MI->getDebugLoc(), get(Mips::SW))
293193323Sed          .addReg(SrcReg, getKillRegState(isKill))
294193323Sed          .addImm(0).addFrameIndex(FI);
295193323Sed      } else {              // COPY -> LOAD
296193323Sed        unsigned DstReg = MI->getOperand(0).getReg();
297193323Sed        bool isDead = MI->getOperand(0).isDead();
298193323Sed        NewMI = BuildMI(MF, MI->getDebugLoc(), get(Mips::LW))
299193323Sed          .addReg(DstReg, RegState::Define | getDeadRegState(isDead))
300193323Sed          .addImm(0).addFrameIndex(FI);
301193323Sed      }
302193323Sed    }
303193323Sed    break;
304193323Sed  case Mips::FMOV_S32:
305193323Sed  case Mips::FMOV_D32:
306193323Sed    if ((MI->getOperand(0).isReg()) &&
307193323Sed        (MI->getOperand(1).isReg())) {
308193323Sed      const TargetRegisterClass
309193323Sed        *RC = RI.getRegClass(MI->getOperand(0).getReg());
310193323Sed      unsigned StoreOpc, LoadOpc;
311193323Sed
312193323Sed      if (RC == Mips::FGR32RegisterClass) {
313193323Sed        LoadOpc = Mips::LWC1; StoreOpc = Mips::SWC1;
314193323Sed      } else {
315193323Sed        assert(RC == Mips::AFGR64RegisterClass);
316193323Sed        LoadOpc = Mips::LDC1; StoreOpc = Mips::SDC1;
317193323Sed      }
318193323Sed
319193323Sed      if (Ops[0] == 0) {    // COPY -> STORE
320193323Sed        unsigned SrcReg = MI->getOperand(1).getReg();
321193323Sed        bool isKill = MI->getOperand(1).isKill();
322193323Sed        NewMI = BuildMI(MF, MI->getDebugLoc(), get(StoreOpc))
323193323Sed          .addReg(SrcReg, getKillRegState(isKill))
324193323Sed          .addImm(0).addFrameIndex(FI) ;
325193323Sed      } else {              // COPY -> LOAD
326193323Sed        unsigned DstReg = MI->getOperand(0).getReg();
327193323Sed        bool isDead = MI->getOperand(0).isDead();
328193323Sed        NewMI = BuildMI(MF, MI->getDebugLoc(), get(LoadOpc))
329193323Sed          .addReg(DstReg, RegState::Define | getDeadRegState(isDead))
330193323Sed          .addImm(0).addFrameIndex(FI);
331193323Sed      }
332193323Sed    }
333193323Sed    break;
334193323Sed  }
335193323Sed
336193323Sed  return NewMI;
337193323Sed}
338193323Sed
339193323Sed//===----------------------------------------------------------------------===//
340193323Sed// Branch Analysis
341193323Sed//===----------------------------------------------------------------------===//
342193323Sed
343193323Sed/// GetCondFromBranchOpc - Return the Mips CC that matches
344193323Sed/// the correspondent Branch instruction opcode.
345193323Sedstatic Mips::CondCode GetCondFromBranchOpc(unsigned BrOpc)
346193323Sed{
347193323Sed  switch (BrOpc) {
348193323Sed  default: return Mips::COND_INVALID;
349193323Sed  case Mips::BEQ  : return Mips::COND_E;
350193323Sed  case Mips::BNE  : return Mips::COND_NE;
351193323Sed  case Mips::BGTZ : return Mips::COND_GZ;
352193323Sed  case Mips::BGEZ : return Mips::COND_GEZ;
353193323Sed  case Mips::BLTZ : return Mips::COND_LZ;
354193323Sed  case Mips::BLEZ : return Mips::COND_LEZ;
355193323Sed
356193323Sed  // We dont do fp branch analysis yet!
357193323Sed  case Mips::BC1T :
358193323Sed  case Mips::BC1F : return Mips::COND_INVALID;
359193323Sed  }
360193323Sed}
361193323Sed
362193323Sed/// GetCondBranchFromCond - Return the Branch instruction
363193323Sed/// opcode that matches the cc.
364193323Sedunsigned Mips::GetCondBranchFromCond(Mips::CondCode CC)
365193323Sed{
366193323Sed  switch (CC) {
367193323Sed  default: assert(0 && "Illegal condition code!");
368193323Sed  case Mips::COND_E   : return Mips::BEQ;
369193323Sed  case Mips::COND_NE  : return Mips::BNE;
370193323Sed  case Mips::COND_GZ  : return Mips::BGTZ;
371193323Sed  case Mips::COND_GEZ : return Mips::BGEZ;
372193323Sed  case Mips::COND_LZ  : return Mips::BLTZ;
373193323Sed  case Mips::COND_LEZ : return Mips::BLEZ;
374193323Sed
375193323Sed  case Mips::FCOND_F:
376193323Sed  case Mips::FCOND_UN:
377193323Sed  case Mips::FCOND_EQ:
378193323Sed  case Mips::FCOND_UEQ:
379193323Sed  case Mips::FCOND_OLT:
380193323Sed  case Mips::FCOND_ULT:
381193323Sed  case Mips::FCOND_OLE:
382193323Sed  case Mips::FCOND_ULE:
383193323Sed  case Mips::FCOND_SF:
384193323Sed  case Mips::FCOND_NGLE:
385193323Sed  case Mips::FCOND_SEQ:
386193323Sed  case Mips::FCOND_NGL:
387193323Sed  case Mips::FCOND_LT:
388193323Sed  case Mips::FCOND_NGE:
389193323Sed  case Mips::FCOND_LE:
390193323Sed  case Mips::FCOND_NGT: return Mips::BC1T;
391193323Sed
392193323Sed  case Mips::FCOND_T:
393193323Sed  case Mips::FCOND_OR:
394193323Sed  case Mips::FCOND_NEQ:
395193323Sed  case Mips::FCOND_OGL:
396193323Sed  case Mips::FCOND_UGE:
397193323Sed  case Mips::FCOND_OGE:
398193323Sed  case Mips::FCOND_UGT:
399193323Sed  case Mips::FCOND_OGT:
400193323Sed  case Mips::FCOND_ST:
401193323Sed  case Mips::FCOND_GLE:
402193323Sed  case Mips::FCOND_SNE:
403193323Sed  case Mips::FCOND_GL:
404193323Sed  case Mips::FCOND_NLT:
405193323Sed  case Mips::FCOND_GE:
406193323Sed  case Mips::FCOND_NLE:
407193323Sed  case Mips::FCOND_GT: return Mips::BC1F;
408193323Sed  }
409193323Sed}
410193323Sed
411193323Sed/// GetOppositeBranchCondition - Return the inverse of the specified
412193323Sed/// condition, e.g. turning COND_E to COND_NE.
413193323SedMips::CondCode Mips::GetOppositeBranchCondition(Mips::CondCode CC)
414193323Sed{
415193323Sed  switch (CC) {
416193323Sed  default: assert(0 && "Illegal condition code!");
417193323Sed  case Mips::COND_E   : return Mips::COND_NE;
418193323Sed  case Mips::COND_NE  : return Mips::COND_E;
419193323Sed  case Mips::COND_GZ  : return Mips::COND_LEZ;
420193323Sed  case Mips::COND_GEZ : return Mips::COND_LZ;
421193323Sed  case Mips::COND_LZ  : return Mips::COND_GEZ;
422193323Sed  case Mips::COND_LEZ : return Mips::COND_GZ;
423193323Sed  case Mips::FCOND_F  : return Mips::FCOND_T;
424193323Sed  case Mips::FCOND_UN : return Mips::FCOND_OR;
425193323Sed  case Mips::FCOND_EQ : return Mips::FCOND_NEQ;
426193323Sed  case Mips::FCOND_UEQ: return Mips::FCOND_OGL;
427193323Sed  case Mips::FCOND_OLT: return Mips::FCOND_UGE;
428193323Sed  case Mips::FCOND_ULT: return Mips::FCOND_OGE;
429193323Sed  case Mips::FCOND_OLE: return Mips::FCOND_UGT;
430193323Sed  case Mips::FCOND_ULE: return Mips::FCOND_OGT;
431193323Sed  case Mips::FCOND_SF:  return Mips::FCOND_ST;
432193323Sed  case Mips::FCOND_NGLE:return Mips::FCOND_GLE;
433193323Sed  case Mips::FCOND_SEQ: return Mips::FCOND_SNE;
434193323Sed  case Mips::FCOND_NGL: return Mips::FCOND_GL;
435193323Sed  case Mips::FCOND_LT:  return Mips::FCOND_NLT;
436193323Sed  case Mips::FCOND_NGE: return Mips::FCOND_GE;
437193323Sed  case Mips::FCOND_LE:  return Mips::FCOND_NLE;
438193323Sed  case Mips::FCOND_NGT: return Mips::FCOND_GT;
439193323Sed  }
440193323Sed}
441193323Sed
442193323Sedbool MipsInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
443193323Sed                                  MachineBasicBlock *&TBB,
444193323Sed                                  MachineBasicBlock *&FBB,
445193323Sed                                  SmallVectorImpl<MachineOperand> &Cond,
446193323Sed                                  bool AllowModify) const
447193323Sed{
448193323Sed  // If the block has no terminators, it just falls into the block after it.
449193323Sed  MachineBasicBlock::iterator I = MBB.end();
450193323Sed  if (I == MBB.begin() || !isUnpredicatedTerminator(--I))
451193323Sed    return false;
452193323Sed
453193323Sed  // Get the last instruction in the block.
454193323Sed  MachineInstr *LastInst = I;
455193323Sed
456193323Sed  // If there is only one terminator instruction, process it.
457193323Sed  unsigned LastOpc = LastInst->getOpcode();
458193323Sed  if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
459193323Sed    if (!LastInst->getDesc().isBranch())
460193323Sed      return true;
461193323Sed
462193323Sed    // Unconditional branch
463193323Sed    if (LastOpc == Mips::J) {
464193323Sed      TBB = LastInst->getOperand(0).getMBB();
465193323Sed      return false;
466193323Sed    }
467193323Sed
468193323Sed    Mips::CondCode BranchCode = GetCondFromBranchOpc(LastInst->getOpcode());
469193323Sed    if (BranchCode == Mips::COND_INVALID)
470193323Sed      return true;  // Can't handle indirect branch.
471193323Sed
472193323Sed    // Conditional branch
473193323Sed    // Block ends with fall-through condbranch.
474193323Sed    if (LastOpc != Mips::COND_INVALID) {
475193323Sed      int LastNumOp = LastInst->getNumOperands();
476193323Sed
477193323Sed      TBB = LastInst->getOperand(LastNumOp-1).getMBB();
478193323Sed      Cond.push_back(MachineOperand::CreateImm(BranchCode));
479193323Sed
480193323Sed      for (int i=0; i<LastNumOp-1; i++) {
481193323Sed        Cond.push_back(LastInst->getOperand(i));
482193323Sed      }
483193323Sed
484193323Sed      return false;
485193323Sed    }
486193323Sed  }
487193323Sed
488193323Sed  // Get the instruction before it if it is a terminator.
489193323Sed  MachineInstr *SecondLastInst = I;
490193323Sed
491193323Sed  // If there are three terminators, we don't know what sort of block this is.
492193323Sed  if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
493193323Sed    return true;
494193323Sed
495193323Sed  // If the block ends with Mips::J and a Mips::BNE/Mips::BEQ, handle it.
496193323Sed  unsigned SecondLastOpc    = SecondLastInst->getOpcode();
497193323Sed  Mips::CondCode BranchCode = GetCondFromBranchOpc(SecondLastOpc);
498193323Sed
499193323Sed  if (BranchCode != Mips::COND_INVALID && LastOpc == Mips::J) {
500193323Sed    int SecondNumOp = SecondLastInst->getNumOperands();
501193323Sed
502193323Sed    TBB = SecondLastInst->getOperand(SecondNumOp-1).getMBB();
503193323Sed    Cond.push_back(MachineOperand::CreateImm(BranchCode));
504193323Sed
505193323Sed    for (int i=0; i<SecondNumOp-1; i++) {
506193323Sed      Cond.push_back(SecondLastInst->getOperand(i));
507193323Sed    }
508193323Sed
509193323Sed    FBB = LastInst->getOperand(0).getMBB();
510193323Sed    return false;
511193323Sed  }
512193323Sed
513193323Sed  // If the block ends with two unconditional branches, handle it. The last
514193323Sed  // one is not executed, so remove it.
515193323Sed  if ((SecondLastOpc == Mips::J) && (LastOpc == Mips::J)) {
516193323Sed    TBB = SecondLastInst->getOperand(0).getMBB();
517193323Sed    I = LastInst;
518193323Sed    if (AllowModify)
519193323Sed      I->eraseFromParent();
520193323Sed    return false;
521193323Sed  }
522193323Sed
523193323Sed  // Otherwise, can't handle this.
524193323Sed  return true;
525193323Sed}
526193323Sed
527193323Sedunsigned MipsInstrInfo::
528193323SedInsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
529193323Sed             MachineBasicBlock *FBB,
530193323Sed             const SmallVectorImpl<MachineOperand> &Cond) const {
531193323Sed  // FIXME this should probably have a DebugLoc argument
532193323Sed  DebugLoc dl = DebugLoc::getUnknownLoc();
533193323Sed  // Shouldn't be a fall through.
534193323Sed  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
535193323Sed  assert((Cond.size() == 3 || Cond.size() == 2 || Cond.size() == 0) &&
536193323Sed         "Mips branch conditions can have two|three components!");
537193323Sed
538193323Sed  if (FBB == 0) { // One way branch.
539193323Sed    if (Cond.empty()) {
540193323Sed      // Unconditional branch?
541193323Sed      BuildMI(&MBB, dl, get(Mips::J)).addMBB(TBB);
542193323Sed    } else {
543193323Sed      // Conditional branch.
544193323Sed      unsigned Opc = GetCondBranchFromCond((Mips::CondCode)Cond[0].getImm());
545193323Sed      const TargetInstrDesc &TID = get(Opc);
546193323Sed
547193323Sed      if (TID.getNumOperands() == 3)
548193323Sed        BuildMI(&MBB, dl, TID).addReg(Cond[1].getReg())
549193323Sed                          .addReg(Cond[2].getReg())
550193323Sed                          .addMBB(TBB);
551193323Sed      else
552193323Sed        BuildMI(&MBB, dl, TID).addReg(Cond[1].getReg())
553193323Sed                          .addMBB(TBB);
554193323Sed
555193323Sed    }
556193323Sed    return 1;
557193323Sed  }
558193323Sed
559193323Sed  // Two-way Conditional branch.
560193323Sed  unsigned Opc = GetCondBranchFromCond((Mips::CondCode)Cond[0].getImm());
561193323Sed  const TargetInstrDesc &TID = get(Opc);
562193323Sed
563193323Sed  if (TID.getNumOperands() == 3)
564193323Sed    BuildMI(&MBB, dl, TID).addReg(Cond[1].getReg()).addReg(Cond[2].getReg())
565193323Sed                      .addMBB(TBB);
566193323Sed  else
567193323Sed    BuildMI(&MBB, dl, TID).addReg(Cond[1].getReg()).addMBB(TBB);
568193323Sed
569193323Sed  BuildMI(&MBB, dl, get(Mips::J)).addMBB(FBB);
570193323Sed  return 2;
571193323Sed}
572193323Sed
573193323Sedunsigned MipsInstrInfo::
574193323SedRemoveBranch(MachineBasicBlock &MBB) const
575193323Sed{
576193323Sed  MachineBasicBlock::iterator I = MBB.end();
577193323Sed  if (I == MBB.begin()) return 0;
578193323Sed  --I;
579193323Sed  if (I->getOpcode() != Mips::J &&
580193323Sed      GetCondFromBranchOpc(I->getOpcode()) == Mips::COND_INVALID)
581193323Sed    return 0;
582193323Sed
583193323Sed  // Remove the branch.
584193323Sed  I->eraseFromParent();
585193323Sed
586193323Sed  I = MBB.end();
587193323Sed
588193323Sed  if (I == MBB.begin()) return 1;
589193323Sed  --I;
590193323Sed  if (GetCondFromBranchOpc(I->getOpcode()) == Mips::COND_INVALID)
591193323Sed    return 1;
592193323Sed
593193323Sed  // Remove the branch.
594193323Sed  I->eraseFromParent();
595193323Sed  return 2;
596193323Sed}
597193323Sed
598193323Sed/// BlockHasNoFallThrough - Analyze if MachineBasicBlock does not
599193323Sed/// fall-through into its successor block.
600193323Sedbool MipsInstrInfo::
601193323SedBlockHasNoFallThrough(const MachineBasicBlock &MBB) const
602193323Sed{
603193323Sed  if (MBB.empty()) return false;
604193323Sed
605193323Sed  switch (MBB.back().getOpcode()) {
606193323Sed  case Mips::RET:     // Return.
607193323Sed  case Mips::JR:      // Indirect branch.
608193323Sed  case Mips::J:       // Uncond branch.
609193323Sed    return true;
610193323Sed  default: return false;
611193323Sed  }
612193323Sed}
613193323Sed
614193323Sed/// ReverseBranchCondition - Return the inverse opcode of the
615193323Sed/// specified Branch instruction.
616193323Sedbool MipsInstrInfo::
617193323SedReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
618193323Sed{
619193323Sed  assert( (Cond.size() == 3 || Cond.size() == 2) &&
620193323Sed          "Invalid Mips branch condition!");
621193323Sed  Cond[0].setImm(GetOppositeBranchCondition((Mips::CondCode)Cond[0].getImm()));
622193323Sed  return false;
623193323Sed}
624