blob: 3305a2ce3283563640baf4a0dc2e6b5ebba5738e [file] [log] [blame]
Akira Hatanaka4552c9a2011-04-15 21:51:11 +00001//===- MipsInstrInfo.cpp - Mips Instruction Information ---------*- C++ -*-===//
Bruno Cardoso Lopes972f5892007-06-06 07:42:06 +00002//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Bruno Cardoso Lopes972f5892007-06-06 07:42:06 +00007//
Akira Hatanaka4552c9a2011-04-15 21:51:11 +00008//===----------------------------------------------------------------------===//
Bruno Cardoso Lopes972f5892007-06-06 07:42:06 +00009//
10// This file contains the Mips implementation of the TargetInstrInfo class.
11//
Akira Hatanaka4552c9a2011-04-15 21:51:11 +000012//===----------------------------------------------------------------------===//
Bruno Cardoso Lopes972f5892007-06-06 07:42:06 +000013
Bruno Cardoso Lopes972f5892007-06-06 07:42:06 +000014#include "MipsInstrInfo.h"
Bruno Cardoso Lopes43d526d2008-07-14 14:42:54 +000015#include "MipsTargetMachine.h"
Dan Gohman99114052009-06-03 20:30:14 +000016#include "MipsMachineFunction.h"
Akira Hatanaka794bf172011-07-07 23:56:50 +000017#include "InstPrinter/MipsInstPrinter.h"
Bruno Cardoso Lopes972f5892007-06-06 07:42:06 +000018#include "llvm/CodeGen/MachineInstrBuilder.h"
Dan Gohman99114052009-06-03 20:30:14 +000019#include "llvm/CodeGen/MachineRegisterInfo.h"
Evan Cheng59ee62d2011-07-11 03:57:24 +000020#include "llvm/Target/TargetRegistry.h"
Torok Edwinc25e7582009-07-11 20:10:48 +000021#include "llvm/Support/ErrorHandling.h"
Evan Cheng59ee62d2011-07-11 03:57:24 +000022#include "llvm/ADT/STLExtras.h"
Evan Cheng22fee2d2011-06-28 20:07:07 +000023
Evan Cheng4db3cff2011-07-01 17:57:27 +000024#define GET_INSTRINFO_CTOR
Evan Cheng22fee2d2011-06-28 20:07:07 +000025#define GET_INSTRINFO_MC_DESC
Bruno Cardoso Lopes972f5892007-06-06 07:42:06 +000026#include "MipsGenInstrInfo.inc"
27
28using namespace llvm;
29
Bruno Cardoso Lopes972f5892007-06-06 07:42:06 +000030MipsInstrInfo::MipsInstrInfo(MipsTargetMachine &tm)
Evan Cheng4db3cff2011-07-01 17:57:27 +000031 : MipsGenInstrInfo(Mips::ADJCALLSTACKDOWN, Mips::ADJCALLSTACKUP),
Bruno Cardoso Lopes43d526d2008-07-14 14:42:54 +000032 TM(tm), RI(*TM.getSubtargetImpl(), *this) {}
Bruno Cardoso Lopes972f5892007-06-06 07:42:06 +000033
Akira Hatanaka794bf172011-07-07 23:56:50 +000034
35const MipsRegisterInfo &MipsInstrInfo::getRegisterInfo() const {
36 return RI;
37}
38
Bruno Cardoso Lopes972f5892007-06-06 07:42:06 +000039static bool isZeroImm(const MachineOperand &op) {
Dan Gohmand735b802008-10-03 15:45:36 +000040 return op.isImm() && op.getImm() == 0;
Bruno Cardoso Lopes972f5892007-06-06 07:42:06 +000041}
42
Bruno Cardoso Lopes972f5892007-06-06 07:42:06 +000043/// isLoadFromStackSlot - If the specified machine instruction is a direct
44/// load from a stack slot, return the virtual or physical register number of
45/// the destination along with the FrameIndex of the loaded stack slot. If
46/// not, return 0. This predicate must return 0 if the instruction has
47/// any side effects other than loading from the stack slot.
48unsigned MipsInstrInfo::
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +000049isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const
Bruno Cardoso Lopes972f5892007-06-06 07:42:06 +000050{
Bruno Cardoso Lopes225ca9c2008-07-05 19:05:21 +000051 if ((MI->getOpcode() == Mips::LW) || (MI->getOpcode() == Mips::LWC1) ||
Bruno Cardoso Lopesbdfbb742009-03-21 00:05:07 +000052 (MI->getOpcode() == Mips::LDC1)) {
Akira Hatanakad3ac47f2011-07-07 18:57:00 +000053 if ((MI->getOperand(1).isFI()) && // is a stack slot
54 (MI->getOperand(2).isImm()) && // the imm is zero
55 (isZeroImm(MI->getOperand(2)))) {
56 FrameIndex = MI->getOperand(1).getIndex();
Bruno Cardoso Lopes972f5892007-06-06 07:42:06 +000057 return MI->getOperand(0).getReg();
58 }
59 }
60
61 return 0;
62}
63
64/// isStoreToStackSlot - If the specified machine instruction is a direct
65/// store to a stack slot, return the virtual or physical register number of
66/// the source reg along with the FrameIndex of the loaded stack slot. If
67/// not, return 0. This predicate must return 0 if the instruction has
68/// any side effects other than storing to the stack slot.
69unsigned MipsInstrInfo::
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +000070isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const
Bruno Cardoso Lopes972f5892007-06-06 07:42:06 +000071{
Bruno Cardoso Lopes225ca9c2008-07-05 19:05:21 +000072 if ((MI->getOpcode() == Mips::SW) || (MI->getOpcode() == Mips::SWC1) ||
Bruno Cardoso Lopesbdfbb742009-03-21 00:05:07 +000073 (MI->getOpcode() == Mips::SDC1)) {
Akira Hatanakad3ac47f2011-07-07 18:57:00 +000074 if ((MI->getOperand(1).isFI()) && // is a stack slot
75 (MI->getOperand(2).isImm()) && // the imm is zero
76 (isZeroImm(MI->getOperand(2)))) {
77 FrameIndex = MI->getOperand(1).getIndex();
Bruno Cardoso Lopes91ef8492008-08-02 19:42:36 +000078 return MI->getOperand(0).getReg();
Bruno Cardoso Lopes972f5892007-06-06 07:42:06 +000079 }
80 }
81 return 0;
82}
83
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +000084/// insertNoop - If data hazard condition is found insert the target nop
85/// instruction.
86void MipsInstrInfo::
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +000087insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +000088{
Chris Lattnerc7f3ace2010-04-02 20:16:16 +000089 DebugLoc DL;
Bill Wendlingd1c321a2009-02-12 00:02:55 +000090 BuildMI(MBB, MI, DL, get(Mips::NOP));
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +000091}
92
Jakob Stoklund Olesen273c14f2010-07-11 01:08:31 +000093void MipsInstrInfo::
94copyPhysReg(MachineBasicBlock &MBB,
95 MachineBasicBlock::iterator I, DebugLoc DL,
96 unsigned DestReg, unsigned SrcReg,
97 bool KillSrc) const {
98 bool DestCPU = Mips::CPURegsRegClass.contains(DestReg);
99 bool SrcCPU = Mips::CPURegsRegClass.contains(SrcReg);
Bill Wendlingd1c321a2009-02-12 00:02:55 +0000100
Jakob Stoklund Olesen273c14f2010-07-11 01:08:31 +0000101 // CPU-CPU is the most common.
102 if (DestCPU && SrcCPU) {
103 BuildMI(MBB, I, DL, get(Mips::ADDu), DestReg).addReg(Mips::ZERO)
104 .addReg(SrcReg, getKillRegState(KillSrc));
105 return;
Bruno Cardoso Lopes225ca9c2008-07-05 19:05:21 +0000106 }
107
Jakob Stoklund Olesen273c14f2010-07-11 01:08:31 +0000108 // Copy to CPU from other registers.
109 if (DestCPU) {
110 if (Mips::CCRRegClass.contains(SrcReg))
111 BuildMI(MBB, I, DL, get(Mips::CFC1), DestReg)
112 .addReg(SrcReg, getKillRegState(KillSrc));
113 else if (Mips::FGR32RegClass.contains(SrcReg))
114 BuildMI(MBB, I, DL, get(Mips::MFC1), DestReg)
115 .addReg(SrcReg, getKillRegState(KillSrc));
116 else if (SrcReg == Mips::HI)
117 BuildMI(MBB, I, DL, get(Mips::MFHI), DestReg);
118 else if (SrcReg == Mips::LO)
119 BuildMI(MBB, I, DL, get(Mips::MFLO), DestReg);
120 else
121 llvm_unreachable("Copy to CPU from invalid register");
122 return;
123 }
124
125 // Copy to other registers from CPU.
126 if (SrcCPU) {
127 if (Mips::CCRRegClass.contains(DestReg))
128 BuildMI(MBB, I, DL, get(Mips::CTC1), DestReg)
129 .addReg(SrcReg, getKillRegState(KillSrc));
130 else if (Mips::FGR32RegClass.contains(DestReg))
131 BuildMI(MBB, I, DL, get(Mips::MTC1), DestReg)
132 .addReg(SrcReg, getKillRegState(KillSrc));
133 else if (DestReg == Mips::HI)
134 BuildMI(MBB, I, DL, get(Mips::MTHI))
135 .addReg(SrcReg, getKillRegState(KillSrc));
136 else if (DestReg == Mips::LO)
137 BuildMI(MBB, I, DL, get(Mips::MTLO))
138 .addReg(SrcReg, getKillRegState(KillSrc));
139 else
140 llvm_unreachable("Copy from CPU to invalid register");
141 return;
142 }
143
144 if (Mips::FGR32RegClass.contains(DestReg, SrcReg)) {
145 BuildMI(MBB, I, DL, get(Mips::FMOV_S32), DestReg)
146 .addReg(SrcReg, getKillRegState(KillSrc));
147 return;
148 }
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000149
Jakob Stoklund Olesen273c14f2010-07-11 01:08:31 +0000150 if (Mips::AFGR64RegClass.contains(DestReg, SrcReg)) {
151 BuildMI(MBB, I, DL, get(Mips::FMOV_D32), DestReg)
152 .addReg(SrcReg, getKillRegState(KillSrc));
153 return;
154 }
155
156 if (Mips::CCRRegClass.contains(DestReg, SrcReg)) {
157 BuildMI(MBB, I, DL, get(Mips::MOVCCRToCCR), DestReg)
158 .addReg(SrcReg, getKillRegState(KillSrc));
159 return;
160 }
161 llvm_unreachable("Cannot copy registers");
Bruno Cardoso Lopes225ca9c2008-07-05 19:05:21 +0000162}
163
164void MipsInstrInfo::
165storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000166 unsigned SrcReg, bool isKill, int FI,
Evan Cheng746ad692010-05-06 19:06:44 +0000167 const TargetRegisterClass *RC,
168 const TargetRegisterInfo *TRI) const {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000169 DebugLoc DL;
Bill Wendlingd1c321a2009-02-12 00:02:55 +0000170 if (I != MBB.end()) DL = I->getDebugLoc();
171
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000172 if (RC == Mips::CPURegsRegisterClass)
Bruno Cardoso Lopes302525b2009-11-25 00:36:00 +0000173 BuildMI(MBB, I, DL, get(Mips::SW)).addReg(SrcReg, getKillRegState(isKill))
Akira Hatanakad3ac47f2011-07-07 18:57:00 +0000174 .addFrameIndex(FI).addImm(0);
Bruno Cardoso Lopes302525b2009-11-25 00:36:00 +0000175 else if (RC == Mips::FGR32RegisterClass)
Akira Hatanaka4552c9a2011-04-15 21:51:11 +0000176 BuildMI(MBB, I, DL, get(Mips::SWC1)).addReg(SrcReg, getKillRegState(isKill))
Akira Hatanakad3ac47f2011-07-07 18:57:00 +0000177 .addFrameIndex(FI).addImm(0);
Bruno Cardoso Lopes302525b2009-11-25 00:36:00 +0000178 else if (RC == Mips::AFGR64RegisterClass) {
179 if (!TM.getSubtarget<MipsSubtarget>().isMips1()) {
180 BuildMI(MBB, I, DL, get(Mips::SDC1))
181 .addReg(SrcReg, getKillRegState(isKill))
Akira Hatanakad3ac47f2011-07-07 18:57:00 +0000182 .addFrameIndex(FI).addImm(0);
Bruno Cardoso Lopes302525b2009-11-25 00:36:00 +0000183 } else {
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000184 const TargetRegisterInfo *TRI =
Bruno Cardoso Lopes302525b2009-11-25 00:36:00 +0000185 MBB.getParent()->getTarget().getRegisterInfo();
186 const unsigned *SubSet = TRI->getSubRegisters(SrcReg);
187 BuildMI(MBB, I, DL, get(Mips::SWC1))
188 .addReg(SubSet[0], getKillRegState(isKill))
Akira Hatanakad3ac47f2011-07-07 18:57:00 +0000189 .addFrameIndex(FI).addImm(0);
Bruno Cardoso Lopes302525b2009-11-25 00:36:00 +0000190 BuildMI(MBB, I, DL, get(Mips::SWC1))
191 .addReg(SubSet[1], getKillRegState(isKill))
Akira Hatanakad3ac47f2011-07-07 18:57:00 +0000192 .addFrameIndex(FI).addImm(4);
Bruno Cardoso Lopes302525b2009-11-25 00:36:00 +0000193 }
194 } else
195 llvm_unreachable("Register class not handled!");
Bruno Cardoso Lopes225ca9c2008-07-05 19:05:21 +0000196}
197
Bruno Cardoso Lopes225ca9c2008-07-05 19:05:21 +0000198void MipsInstrInfo::
199loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
200 unsigned DestReg, int FI,
Evan Cheng746ad692010-05-06 19:06:44 +0000201 const TargetRegisterClass *RC,
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000202 const TargetRegisterInfo *TRI) const
Bruno Cardoso Lopes225ca9c2008-07-05 19:05:21 +0000203{
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000204 DebugLoc DL;
Bill Wendlingd1c321a2009-02-12 00:02:55 +0000205 if (I != MBB.end()) DL = I->getDebugLoc();
Bruno Cardoso Lopes302525b2009-11-25 00:36:00 +0000206
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000207 if (RC == Mips::CPURegsRegisterClass)
Akira Hatanakad3ac47f2011-07-07 18:57:00 +0000208 BuildMI(MBB, I, DL, get(Mips::LW), DestReg).addFrameIndex(FI).addImm(0);
Bruno Cardoso Lopes302525b2009-11-25 00:36:00 +0000209 else if (RC == Mips::FGR32RegisterClass)
Akira Hatanakad3ac47f2011-07-07 18:57:00 +0000210 BuildMI(MBB, I, DL, get(Mips::LWC1), DestReg).addFrameIndex(FI).addImm(0);
Bruno Cardoso Lopes302525b2009-11-25 00:36:00 +0000211 else if (RC == Mips::AFGR64RegisterClass) {
212 if (!TM.getSubtarget<MipsSubtarget>().isMips1()) {
Akira Hatanakad3ac47f2011-07-07 18:57:00 +0000213 BuildMI(MBB, I, DL, get(Mips::LDC1), DestReg).addFrameIndex(FI).addImm(0);
Bruno Cardoso Lopes302525b2009-11-25 00:36:00 +0000214 } else {
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000215 const TargetRegisterInfo *TRI =
Bruno Cardoso Lopes302525b2009-11-25 00:36:00 +0000216 MBB.getParent()->getTarget().getRegisterInfo();
217 const unsigned *SubSet = TRI->getSubRegisters(DestReg);
218 BuildMI(MBB, I, DL, get(Mips::LWC1), SubSet[0])
Akira Hatanakad3ac47f2011-07-07 18:57:00 +0000219 .addFrameIndex(FI).addImm(0);
Bruno Cardoso Lopes302525b2009-11-25 00:36:00 +0000220 BuildMI(MBB, I, DL, get(Mips::LWC1), SubSet[1])
Akira Hatanakad3ac47f2011-07-07 18:57:00 +0000221 .addFrameIndex(FI).addImm(4);
Bruno Cardoso Lopes302525b2009-11-25 00:36:00 +0000222 }
223 } else
224 llvm_unreachable("Register class not handled!");
Bruno Cardoso Lopes225ca9c2008-07-05 19:05:21 +0000225}
226
Akira Hatanakac4f24eb2011-07-01 01:04:43 +0000227MachineInstr*
228MipsInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx,
229 uint64_t Offset, const MDNode *MDPtr,
230 DebugLoc DL) const {
231 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Mips::DBG_VALUE))
232 .addFrameIndex(FrameIx).addImm(0).addImm(Offset).addMetadata(MDPtr);
233 return &*MIB;
234}
235
Akira Hatanaka4552c9a2011-04-15 21:51:11 +0000236//===----------------------------------------------------------------------===//
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000237// Branch Analysis
Akira Hatanaka4552c9a2011-04-15 21:51:11 +0000238//===----------------------------------------------------------------------===//
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000239
Akira Hatanaka20ada982011-04-01 17:39:08 +0000240static unsigned GetAnalyzableBrOpc(unsigned Opc) {
241 return (Opc == Mips::BEQ || Opc == Mips::BNE || Opc == Mips::BGTZ ||
242 Opc == Mips::BGEZ || Opc == Mips::BLTZ || Opc == Mips::BLEZ ||
243 Opc == Mips::BC1T || Opc == Mips::BC1F || Opc == Mips::J) ? Opc : 0;
244}
Bruno Cardoso Lopes85e31e32008-07-28 19:11:24 +0000245
Akira Hatanaka20ada982011-04-01 17:39:08 +0000246/// GetOppositeBranchOpc - Return the inverse of the specified
247/// opcode, e.g. turning BEQ to BNE.
248unsigned Mips::GetOppositeBranchOpc(unsigned Opc)
249{
250 switch (Opc) {
251 default: llvm_unreachable("Illegal opcode!");
252 case Mips::BEQ : return Mips::BNE;
253 case Mips::BNE : return Mips::BEQ;
254 case Mips::BGTZ : return Mips::BLEZ;
255 case Mips::BGEZ : return Mips::BLTZ;
256 case Mips::BLTZ : return Mips::BGEZ;
257 case Mips::BLEZ : return Mips::BGTZ;
258 case Mips::BC1T : return Mips::BC1F;
259 case Mips::BC1F : return Mips::BC1T;
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000260 }
261}
262
Akira Hatanaka20ada982011-04-01 17:39:08 +0000263static void AnalyzeCondBr(const MachineInstr* Inst, unsigned Opc,
264 MachineBasicBlock *&BB,
265 SmallVectorImpl<MachineOperand>& Cond) {
266 assert(GetAnalyzableBrOpc(Opc) && "Not an analyzable branch");
267 int NumOp = Inst->getNumExplicitOperands();
268
269 // for both int and fp branches, the last explicit operand is the
270 // MBB.
271 BB = Inst->getOperand(NumOp-1).getMBB();
272 Cond.push_back(MachineOperand::CreateImm(Opc));
Bruno Cardoso Lopes85e31e32008-07-28 19:11:24 +0000273
Akira Hatanaka20ada982011-04-01 17:39:08 +0000274 for (int i=0; i<NumOp-1; i++)
275 Cond.push_back(Inst->getOperand(i));
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000276}
277
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000278bool MipsInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000279 MachineBasicBlock *&TBB,
280 MachineBasicBlock *&FBB,
Evan Chengdc54d312009-02-09 07:14:22 +0000281 SmallVectorImpl<MachineOperand> &Cond,
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000282 bool AllowModify) const
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000283{
Akira Hatanaka20ada982011-04-01 17:39:08 +0000284 MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000285
Akira Hatanaka20ada982011-04-01 17:39:08 +0000286 // Skip all the debug instructions.
287 while (I != REnd && I->isDebugValue())
288 ++I;
289
290 if (I == REnd || !isUnpredicatedTerminator(&*I)) {
291 // If this block ends with no branches (it just falls through to its succ)
292 // just return false, leaving TBB/FBB null.
293 TBB = FBB = NULL;
294 return false;
295 }
296
297 MachineInstr *LastInst = &*I;
298 unsigned LastOpc = LastInst->getOpcode();
299
300 // Not an analyzable branch (must be an indirect jump).
301 if (!GetAnalyzableBrOpc(LastOpc))
302 return true;
303
304 // Get the second to last instruction in the block.
305 unsigned SecondLastOpc = 0;
306 MachineInstr *SecondLastInst = NULL;
307
308 if (++I != REnd) {
309 SecondLastInst = &*I;
310 SecondLastOpc = GetAnalyzableBrOpc(SecondLastInst->getOpcode());
311
312 // Not an analyzable branch (must be an indirect jump).
313 if (isUnpredicatedTerminator(SecondLastInst) && !SecondLastOpc)
314 return true;
315 }
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000316
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000317 // If there is only one terminator instruction, process it.
Akira Hatanaka20ada982011-04-01 17:39:08 +0000318 if (!SecondLastOpc) {
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000319 // Unconditional branch
320 if (LastOpc == Mips::J) {
Chris Lattner8aa797a2007-12-30 23:10:15 +0000321 TBB = LastInst->getOperand(0).getMBB();
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000322 return false;
323 }
324
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000325 // Conditional branch
Akira Hatanaka20ada982011-04-01 17:39:08 +0000326 AnalyzeCondBr(LastInst, LastOpc, TBB, Cond);
327 return false;
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000328 }
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000329
Akira Hatanaka20ada982011-04-01 17:39:08 +0000330 // If we reached here, there are two branches.
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000331 // If there are three terminators, we don't know what sort of block this is.
Akira Hatanaka20ada982011-04-01 17:39:08 +0000332 if (++I != REnd && isUnpredicatedTerminator(&*I))
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000333 return true;
334
Akira Hatanaka20ada982011-04-01 17:39:08 +0000335 // If second to last instruction is an unconditional branch,
336 // analyze it and remove the last instruction.
337 if (SecondLastOpc == Mips::J) {
338 // Return if the last instruction cannot be removed.
339 if (!AllowModify)
340 return true;
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000341
Chris Lattner8aa797a2007-12-30 23:10:15 +0000342 TBB = SecondLastInst->getOperand(0).getMBB();
Akira Hatanaka20ada982011-04-01 17:39:08 +0000343 LastInst->eraseFromParent();
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000344 return false;
345 }
346
Akira Hatanaka20ada982011-04-01 17:39:08 +0000347 // Conditional branch followed by an unconditional branch.
348 // The last one must be unconditional.
349 if (LastOpc != Mips::J)
350 return true;
351
352 AnalyzeCondBr(SecondLastInst, SecondLastOpc, TBB, Cond);
353 FBB = LastInst->getOperand(0).getMBB();
354
355 return false;
356}
357
358void MipsInstrInfo::BuildCondBr(MachineBasicBlock &MBB,
359 MachineBasicBlock *TBB, DebugLoc DL,
360 const SmallVectorImpl<MachineOperand>& Cond)
361 const {
362 unsigned Opc = Cond[0].getImm();
Evan Chenge837dea2011-06-28 19:10:37 +0000363 const MCInstrDesc &MCID = get(Opc);
364 MachineInstrBuilder MIB = BuildMI(&MBB, DL, MCID);
Akira Hatanaka20ada982011-04-01 17:39:08 +0000365
366 for (unsigned i = 1; i < Cond.size(); ++i)
367 MIB.addReg(Cond[i].getReg());
368
369 MIB.addMBB(TBB);
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000370}
371
Bruno Cardoso Lopes972f5892007-06-06 07:42:06 +0000372unsigned MipsInstrInfo::
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000373InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
Owen Anderson44eb65c2008-08-14 22:49:33 +0000374 MachineBasicBlock *FBB,
Stuart Hastings3bf91252010-06-17 22:43:56 +0000375 const SmallVectorImpl<MachineOperand> &Cond,
376 DebugLoc DL) const {
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000377 // Shouldn't be a fall through.
378 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000379
Akira Hatanaka20ada982011-04-01 17:39:08 +0000380 // # of condition operands:
381 // Unconditional branches: 0
382 // Floating point branches: 1 (opc)
383 // Int BranchZero: 2 (opc, reg)
384 // Int Branch: 3 (opc, reg0, reg1)
385 assert((Cond.size() <= 3) &&
386 "# of Mips branch conditions must be <= 3!");
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000387
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000388 // Two-way Conditional branch.
Akira Hatanaka20ada982011-04-01 17:39:08 +0000389 if (FBB) {
390 BuildCondBr(MBB, TBB, DL, Cond);
391 BuildMI(&MBB, DL, get(Mips::J)).addMBB(FBB);
392 return 2;
393 }
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000394
Akira Hatanaka20ada982011-04-01 17:39:08 +0000395 // One way branch.
396 // Unconditional branch.
397 if (Cond.empty())
398 BuildMI(&MBB, DL, get(Mips::J)).addMBB(TBB);
399 else // Conditional branch.
400 BuildCondBr(MBB, TBB, DL, Cond);
401 return 1;
Bruno Cardoso Lopes972f5892007-06-06 07:42:06 +0000402}
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000403
404unsigned MipsInstrInfo::
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000405RemoveBranch(MachineBasicBlock &MBB) const
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000406{
Akira Hatanaka20ada982011-04-01 17:39:08 +0000407 MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();
408 MachineBasicBlock::reverse_iterator FirstBr;
409 unsigned removed;
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000410
Akira Hatanaka20ada982011-04-01 17:39:08 +0000411 // Skip all the debug instructions.
412 while (I != REnd && I->isDebugValue())
413 ++I;
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000414
Akira Hatanaka20ada982011-04-01 17:39:08 +0000415 FirstBr = I;
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000416
Akira Hatanaka20ada982011-04-01 17:39:08 +0000417 // Up to 2 branches are removed.
418 // Note that indirect branches are not removed.
419 for(removed = 0; I != REnd && removed < 2; ++I, ++removed)
420 if (!GetAnalyzableBrOpc(I->getOpcode()))
421 break;
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000422
Akira Hatanaka20ada982011-04-01 17:39:08 +0000423 MBB.erase(I.base(), FirstBr.base());
424
425 return removed;
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000426}
427
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000428/// ReverseBranchCondition - Return the inverse opcode of the
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000429/// specified Branch instruction.
430bool MipsInstrInfo::
Bruno Cardoso Lopes81092dc2011-03-04 17:51:39 +0000431ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000432{
Akira Hatanaka20ada982011-04-01 17:39:08 +0000433 assert( (Cond.size() && Cond.size() <= 3) &&
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000434 "Invalid Mips branch condition!");
Akira Hatanaka20ada982011-04-01 17:39:08 +0000435 Cond[0].setImm(Mips::GetOppositeBranchOpc(Cond[0].getImm()));
Bruno Cardoso Lopes35d2a472007-08-18 01:56:48 +0000436 return false;
437}
Dan Gohman99114052009-06-03 20:30:14 +0000438
439/// getGlobalBaseReg - Return a virtual register initialized with the
440/// the global base register value. Output instructions required to
441/// initialize the register in the function entry block, if necessary.
442///
443unsigned MipsInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
444 MipsFunctionInfo *MipsFI = MF->getInfo<MipsFunctionInfo>();
445 unsigned GlobalBaseReg = MipsFI->getGlobalBaseReg();
446 if (GlobalBaseReg != 0)
447 return GlobalBaseReg;
448
449 // Insert the set of GlobalBaseReg into the first MBB of the function
450 MachineBasicBlock &FirstMBB = MF->front();
451 MachineBasicBlock::iterator MBBI = FirstMBB.begin();
452 MachineRegisterInfo &RegInfo = MF->getRegInfo();
453 const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
454
455 GlobalBaseReg = RegInfo.createVirtualRegister(Mips::CPURegsRegisterClass);
Jakob Stoklund Olesen3ecf1f02010-07-10 22:43:03 +0000456 BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY),
457 GlobalBaseReg).addReg(Mips::GP);
Dan Gohman99114052009-06-03 20:30:14 +0000458 RegInfo.addLiveIn(Mips::GP);
459
460 MipsFI->setGlobalBaseReg(GlobalBaseReg);
461 return GlobalBaseReg;
462}
Evan Cheng59ee62d2011-07-11 03:57:24 +0000463
464MCInstrInfo *createMipsMCInstrInfo() {
465 MCInstrInfo *X = new MCInstrInfo();
466 InitMipsMCInstrInfo(X);
467 return X;
468}
469
470extern "C" void LLVMInitializeMipsMCInstrInfo() {
471 TargetRegistry::RegisterMCInstrInfo(TheMipsTarget, createMipsMCInstrInfo);
472}