blob: 8f7d956ccba51680c55cbb579c305bfb7d7928a9 [file] [log] [blame]
Wesley Pecka70f28c2010-02-23 19:15:24 +00001//===- MBlazeInstrInfo.cpp - MBlaze Instruction Information -----*- C++ -*-===//
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 MBlaze implementation of the TargetInstrInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "MBlazeInstrInfo.h"
15#include "MBlazeTargetMachine.h"
16#include "MBlazeMachineFunction.h"
Wesley Pecka70f28c2010-02-23 19:15:24 +000017#include "llvm/CodeGen/MachineInstrBuilder.h"
18#include "llvm/CodeGen/MachineRegisterInfo.h"
Wesley Peck3d820ba2011-04-11 22:31:52 +000019#include "llvm/CodeGen/ScoreboardHazardRecognizer.h"
Evan Cheng59ee62d2011-07-11 03:57:24 +000020#include "llvm/Target/TargetRegistry.h"
Wesley Peck3d820ba2011-04-11 22:31:52 +000021#include "llvm/Support/CommandLine.h"
Wesley Pecka70f28c2010-02-23 19:15:24 +000022#include "llvm/Support/ErrorHandling.h"
Evan Cheng59ee62d2011-07-11 03:57:24 +000023#include "llvm/ADT/STLExtras.h"
Evan Cheng22fee2d2011-06-28 20:07:07 +000024
Evan Cheng4db3cff2011-07-01 17:57:27 +000025#define GET_INSTRINFO_CTOR
Evan Cheng22fee2d2011-06-28 20:07:07 +000026#define GET_INSTRINFO_MC_DESC
Wesley Pecka70f28c2010-02-23 19:15:24 +000027#include "MBlazeGenInstrInfo.inc"
28
29using namespace llvm;
30
31MBlazeInstrInfo::MBlazeInstrInfo(MBlazeTargetMachine &tm)
Evan Cheng4db3cff2011-07-01 17:57:27 +000032 : MBlazeGenInstrInfo(MBlaze::ADJCALLSTACKDOWN, MBlaze::ADJCALLSTACKUP),
Wesley Pecka70f28c2010-02-23 19:15:24 +000033 TM(tm), RI(*TM.getSubtargetImpl(), *this) {}
34
35static bool isZeroImm(const MachineOperand &op) {
36 return op.isImm() && op.getImm() == 0;
37}
38
Wesley Pecka70f28c2010-02-23 19:15:24 +000039/// isLoadFromStackSlot - If the specified machine instruction is a direct
40/// load from a stack slot, return the virtual or physical register number of
41/// the destination along with the FrameIndex of the loaded stack slot. If
42/// not, return 0. This predicate must return 0 if the instruction has
43/// any side effects other than loading from the stack slot.
44unsigned MBlazeInstrInfo::
45isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const {
46 if (MI->getOpcode() == MBlaze::LWI) {
Wesley Peck41400da2010-11-12 23:30:17 +000047 if ((MI->getOperand(1).isFI()) && // is a stack slot
48 (MI->getOperand(2).isImm()) && // the imm is zero
49 (isZeroImm(MI->getOperand(2)))) {
50 FrameIndex = MI->getOperand(1).getIndex();
Wesley Pecka70f28c2010-02-23 19:15:24 +000051 return MI->getOperand(0).getReg();
52 }
53 }
54
55 return 0;
56}
57
58/// isStoreToStackSlot - If the specified machine instruction is a direct
59/// store to a stack slot, return the virtual or physical register number of
60/// the source reg along with the FrameIndex of the loaded stack slot. If
61/// not, return 0. This predicate must return 0 if the instruction has
62/// any side effects other than storing to the stack slot.
63unsigned MBlazeInstrInfo::
64isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const {
65 if (MI->getOpcode() == MBlaze::SWI) {
Wesley Peck41400da2010-11-12 23:30:17 +000066 if ((MI->getOperand(1).isFI()) && // is a stack slot
67 (MI->getOperand(2).isImm()) && // the imm is zero
68 (isZeroImm(MI->getOperand(2)))) {
69 FrameIndex = MI->getOperand(1).getIndex();
Wesley Pecka70f28c2010-02-23 19:15:24 +000070 return MI->getOperand(0).getReg();
71 }
72 }
73 return 0;
74}
75
76/// insertNoop - If data hazard condition is found insert the target nop
77/// instruction.
78void MBlazeInstrInfo::
79insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +000080 DebugLoc DL;
Wesley Pecka70f28c2010-02-23 19:15:24 +000081 BuildMI(MBB, MI, DL, get(MBlaze::NOP));
82}
83
Jakob Stoklund Olesene6afcf82010-07-11 06:53:27 +000084void MBlazeInstrInfo::
85copyPhysReg(MachineBasicBlock &MBB,
86 MachineBasicBlock::iterator I, DebugLoc DL,
87 unsigned DestReg, unsigned SrcReg,
88 bool KillSrc) const {
Wesley Peck9eb337a2010-12-22 01:29:32 +000089 llvm::BuildMI(MBB, I, DL, get(MBlaze::ADDK), DestReg)
Jakob Stoklund Olesene6afcf82010-07-11 06:53:27 +000090 .addReg(SrcReg, getKillRegState(KillSrc)).addReg(MBlaze::R0);
Wesley Pecka70f28c2010-02-23 19:15:24 +000091}
92
93void MBlazeInstrInfo::
94storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
95 unsigned SrcReg, bool isKill, int FI,
Evan Cheng746ad692010-05-06 19:06:44 +000096 const TargetRegisterClass *RC,
97 const TargetRegisterInfo *TRI) const {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +000098 DebugLoc DL;
99 BuildMI(MBB, I, DL, get(MBlaze::SWI)).addReg(SrcReg,getKillRegState(isKill))
Wesley Peck41400da2010-11-12 23:30:17 +0000100 .addFrameIndex(FI).addImm(0); //.addFrameIndex(FI);
Wesley Pecka70f28c2010-02-23 19:15:24 +0000101}
102
103void MBlazeInstrInfo::
104loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
105 unsigned DestReg, int FI,
Evan Cheng746ad692010-05-06 19:06:44 +0000106 const TargetRegisterClass *RC,
107 const TargetRegisterInfo *TRI) const {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000108 DebugLoc DL;
109 BuildMI(MBB, I, DL, get(MBlaze::LWI), DestReg)
Wesley Peck41400da2010-11-12 23:30:17 +0000110 .addFrameIndex(FI).addImm(0); //.addFrameIndex(FI);
Wesley Pecka70f28c2010-02-23 19:15:24 +0000111}
112
Wesley Pecka70f28c2010-02-23 19:15:24 +0000113//===----------------------------------------------------------------------===//
114// Branch Analysis
115//===----------------------------------------------------------------------===//
Wesley Peck46a928b2010-11-21 21:53:36 +0000116bool MBlazeInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
117 MachineBasicBlock *&TBB,
118 MachineBasicBlock *&FBB,
119 SmallVectorImpl<MachineOperand> &Cond,
120 bool AllowModify) const {
121 // If the block has no terminators, it just falls into the block after it.
122 MachineBasicBlock::iterator I = MBB.end();
123 if (I == MBB.begin())
124 return false;
125 --I;
126 while (I->isDebugValue()) {
127 if (I == MBB.begin())
128 return false;
129 --I;
130 }
131 if (!isUnpredicatedTerminator(I))
132 return false;
133
134 // Get the last instruction in the block.
135 MachineInstr *LastInst = I;
136
137 // If there is only one terminator instruction, process it.
138 unsigned LastOpc = LastInst->getOpcode();
139 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
140 if (MBlaze::isUncondBranchOpcode(LastOpc)) {
141 TBB = LastInst->getOperand(0).getMBB();
142 return false;
143 }
144 if (MBlaze::isCondBranchOpcode(LastOpc)) {
145 // Block ends with fall-through condbranch.
146 TBB = LastInst->getOperand(1).getMBB();
147 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
148 Cond.push_back(LastInst->getOperand(0));
149 return false;
150 }
151 // Otherwise, don't know what this is.
152 return true;
153 }
154
155 // Get the instruction before it if it's a terminator.
156 MachineInstr *SecondLastInst = I;
157
158 // If there are three terminators, we don't know what sort of block this is.
159 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
160 return true;
161
162 // If the block ends with something like BEQID then BRID, handle it.
163 if (MBlaze::isCondBranchOpcode(SecondLastInst->getOpcode()) &&
164 MBlaze::isUncondBranchOpcode(LastInst->getOpcode())) {
165 TBB = SecondLastInst->getOperand(1).getMBB();
166 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
167 Cond.push_back(SecondLastInst->getOperand(0));
168 FBB = LastInst->getOperand(0).getMBB();
169 return false;
170 }
171
172 // If the block ends with two unconditional branches, handle it.
173 // The second one is not executed, so remove it.
174 if (MBlaze::isUncondBranchOpcode(SecondLastInst->getOpcode()) &&
175 MBlaze::isUncondBranchOpcode(LastInst->getOpcode())) {
176 TBB = SecondLastInst->getOperand(0).getMBB();
177 I = LastInst;
178 if (AllowModify)
179 I->eraseFromParent();
180 return false;
181 }
182
183 // Otherwise, can't handle this.
184 return true;
185}
186
Wesley Pecka70f28c2010-02-23 19:15:24 +0000187unsigned MBlazeInstrInfo::
188InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
189 MachineBasicBlock *FBB,
Stuart Hastings3bf91252010-06-17 22:43:56 +0000190 const SmallVectorImpl<MachineOperand> &Cond,
191 DebugLoc DL) const {
Wesley Peck46a928b2010-11-21 21:53:36 +0000192 // Shouldn't be a fall through.
193 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
194 assert((Cond.size() == 2 || Cond.size() == 0) &&
195 "MBlaze branch conditions have two components!");
196
197 unsigned Opc = MBlaze::BRID;
198 if (!Cond.empty())
199 Opc = (unsigned)Cond[0].getImm();
200
201 if (FBB == 0) {
202 if (Cond.empty()) // Unconditional branch
203 BuildMI(&MBB, DL, get(Opc)).addMBB(TBB);
204 else // Conditional branch
205 BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()).addMBB(TBB);
206 return 1;
207 }
208
209 BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()).addMBB(TBB);
210 BuildMI(&MBB, DL, get(MBlaze::BRID)).addMBB(FBB);
211 return 2;
Wesley Pecka70f28c2010-02-23 19:15:24 +0000212}
213
Wesley Peck46a928b2010-11-21 21:53:36 +0000214unsigned MBlazeInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
215 MachineBasicBlock::iterator I = MBB.end();
216 if (I == MBB.begin()) return 0;
217 --I;
218 while (I->isDebugValue()) {
219 if (I == MBB.begin())
220 return 0;
221 --I;
222 }
223
224 if (!MBlaze::isUncondBranchOpcode(I->getOpcode()) &&
225 !MBlaze::isCondBranchOpcode(I->getOpcode()))
226 return 0;
227
228 // Remove the branch.
229 I->eraseFromParent();
230
231 I = MBB.end();
232
233 if (I == MBB.begin()) return 1;
234 --I;
235 if (!MBlaze::isCondBranchOpcode(I->getOpcode()))
236 return 1;
237
238 // Remove the branch.
239 I->eraseFromParent();
240 return 2;
241}
242
Wesley Peck2e063982010-12-02 16:17:11 +0000243bool MBlazeInstrInfo::ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
244 assert(Cond.size() == 2 && "Invalid MBlaze branch opcode!");
245 switch (Cond[0].getImm()) {
246 default: return true;
247 case MBlaze::BEQ: Cond[0].setImm(MBlaze::BNE); return false;
248 case MBlaze::BNE: Cond[0].setImm(MBlaze::BEQ); return false;
249 case MBlaze::BGT: Cond[0].setImm(MBlaze::BLE); return false;
250 case MBlaze::BGE: Cond[0].setImm(MBlaze::BLT); return false;
251 case MBlaze::BLT: Cond[0].setImm(MBlaze::BGE); return false;
252 case MBlaze::BLE: Cond[0].setImm(MBlaze::BGT); return false;
253 case MBlaze::BEQI: Cond[0].setImm(MBlaze::BNEI); return false;
254 case MBlaze::BNEI: Cond[0].setImm(MBlaze::BEQI); return false;
255 case MBlaze::BGTI: Cond[0].setImm(MBlaze::BLEI); return false;
256 case MBlaze::BGEI: Cond[0].setImm(MBlaze::BLTI); return false;
257 case MBlaze::BLTI: Cond[0].setImm(MBlaze::BGEI); return false;
258 case MBlaze::BLEI: Cond[0].setImm(MBlaze::BGTI); return false;
259 case MBlaze::BEQD: Cond[0].setImm(MBlaze::BNED); return false;
260 case MBlaze::BNED: Cond[0].setImm(MBlaze::BEQD); return false;
261 case MBlaze::BGTD: Cond[0].setImm(MBlaze::BLED); return false;
262 case MBlaze::BGED: Cond[0].setImm(MBlaze::BLTD); return false;
263 case MBlaze::BLTD: Cond[0].setImm(MBlaze::BGED); return false;
264 case MBlaze::BLED: Cond[0].setImm(MBlaze::BGTD); return false;
265 case MBlaze::BEQID: Cond[0].setImm(MBlaze::BNEID); return false;
266 case MBlaze::BNEID: Cond[0].setImm(MBlaze::BEQID); return false;
267 case MBlaze::BGTID: Cond[0].setImm(MBlaze::BLEID); return false;
268 case MBlaze::BGEID: Cond[0].setImm(MBlaze::BLTID); return false;
269 case MBlaze::BLTID: Cond[0].setImm(MBlaze::BGEID); return false;
270 case MBlaze::BLEID: Cond[0].setImm(MBlaze::BGTID); return false;
271 }
272}
Wesley Peck46a928b2010-11-21 21:53:36 +0000273
Wesley Pecka70f28c2010-02-23 19:15:24 +0000274/// getGlobalBaseReg - Return a virtual register initialized with the
275/// the global base register value. Output instructions required to
276/// initialize the register in the function entry block, if necessary.
277///
278unsigned MBlazeInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
279 MBlazeFunctionInfo *MBlazeFI = MF->getInfo<MBlazeFunctionInfo>();
280 unsigned GlobalBaseReg = MBlazeFI->getGlobalBaseReg();
281 if (GlobalBaseReg != 0)
282 return GlobalBaseReg;
283
284 // Insert the set of GlobalBaseReg into the first MBB of the function
285 MachineBasicBlock &FirstMBB = MF->front();
286 MachineBasicBlock::iterator MBBI = FirstMBB.begin();
287 MachineRegisterInfo &RegInfo = MF->getRegInfo();
288 const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
289
Wesley Peck4da992a2010-10-21 19:48:38 +0000290 GlobalBaseReg = RegInfo.createVirtualRegister(MBlaze::GPRRegisterClass);
Jakob Stoklund Olesen3ecf1f02010-07-10 22:43:03 +0000291 BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY),
292 GlobalBaseReg).addReg(MBlaze::R20);
Wesley Pecka70f28c2010-02-23 19:15:24 +0000293 RegInfo.addLiveIn(MBlaze::R20);
294
295 MBlazeFI->setGlobalBaseReg(GlobalBaseReg);
296 return GlobalBaseReg;
297}
Evan Cheng59ee62d2011-07-11 03:57:24 +0000298
299MCInstrInfo *createMBlazeMCInstrInfo() {
300 MCInstrInfo *X = new MCInstrInfo();
301 InitMBlazeMCInstrInfo(X);
302 return X;
303}
304
305extern "C" void LLVMInitializeMBlazeMCInstrInfo() {
306 TargetRegistry::RegisterMCInstrInfo(TheMBlazeTarget, createMBlazeMCInstrInfo);
307}