1 //===- MBlazeInstrInfo.cpp - MBlaze Instruction Information -----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the MBlaze implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
14 #include "MBlazeInstrInfo.h"
15 #include "MBlazeTargetMachine.h"
16 #include "MBlazeMachineFunction.h"
17 #include "llvm/CodeGen/MachineInstrBuilder.h"
18 #include "llvm/CodeGen/MachineRegisterInfo.h"
19 #include "llvm/CodeGen/ScoreboardHazardRecognizer.h"
20 #include "llvm/Target/TargetRegistry.h"
21 #include "llvm/Support/CommandLine.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/ADT/STLExtras.h"
25 #define GET_INSTRINFO_CTOR
26 #define GET_INSTRINFO_MC_DESC
27 #include "MBlazeGenInstrInfo.inc"
31 MBlazeInstrInfo::MBlazeInstrInfo(MBlazeTargetMachine &tm)
32 : MBlazeGenInstrInfo(MBlaze::ADJCALLSTACKDOWN, MBlaze::ADJCALLSTACKUP),
33 TM(tm), RI(*TM.getSubtargetImpl(), *this) {}
35 static bool isZeroImm(const MachineOperand &op) {
36 return op.isImm() && op.getImm() == 0;
39 /// 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.
44 unsigned MBlazeInstrInfo::
45 isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const {
46 if (MI->getOpcode() == MBlaze::LWI) {
47 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();
51 return MI->getOperand(0).getReg();
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.
63 unsigned MBlazeInstrInfo::
64 isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const {
65 if (MI->getOpcode() == MBlaze::SWI) {
66 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();
70 return MI->getOperand(0).getReg();
76 /// insertNoop - If data hazard condition is found insert the target nop
78 void MBlazeInstrInfo::
79 insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const {
81 BuildMI(MBB, MI, DL, get(MBlaze::NOP));
84 void MBlazeInstrInfo::
85 copyPhysReg(MachineBasicBlock &MBB,
86 MachineBasicBlock::iterator I, DebugLoc DL,
87 unsigned DestReg, unsigned SrcReg,
89 llvm::BuildMI(MBB, I, DL, get(MBlaze::ADDK), DestReg)
90 .addReg(SrcReg, getKillRegState(KillSrc)).addReg(MBlaze::R0);
93 void MBlazeInstrInfo::
94 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
95 unsigned SrcReg, bool isKill, int FI,
96 const TargetRegisterClass *RC,
97 const TargetRegisterInfo *TRI) const {
99 BuildMI(MBB, I, DL, get(MBlaze::SWI)).addReg(SrcReg,getKillRegState(isKill))
100 .addFrameIndex(FI).addImm(0); //.addFrameIndex(FI);
103 void MBlazeInstrInfo::
104 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
105 unsigned DestReg, int FI,
106 const TargetRegisterClass *RC,
107 const TargetRegisterInfo *TRI) const {
109 BuildMI(MBB, I, DL, get(MBlaze::LWI), DestReg)
110 .addFrameIndex(FI).addImm(0); //.addFrameIndex(FI);
113 //===----------------------------------------------------------------------===//
115 //===----------------------------------------------------------------------===//
116 bool 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())
126 while (I->isDebugValue()) {
127 if (I == MBB.begin())
131 if (!isUnpredicatedTerminator(I))
134 // Get the last instruction in the block.
135 MachineInstr *LastInst = I;
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();
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));
151 // Otherwise, don't know what this is.
155 // Get the instruction before it if it's a terminator.
156 MachineInstr *SecondLastInst = I;
158 // If there are three terminators, we don't know what sort of block this is.
159 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
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();
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();
179 I->eraseFromParent();
183 // Otherwise, can't handle this.
187 unsigned MBlazeInstrInfo::
188 InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
189 MachineBasicBlock *FBB,
190 const SmallVectorImpl<MachineOperand> &Cond,
192 // 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!");
197 unsigned Opc = MBlaze::BRID;
199 Opc = (unsigned)Cond[0].getImm();
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);
209 BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()).addMBB(TBB);
210 BuildMI(&MBB, DL, get(MBlaze::BRID)).addMBB(FBB);
214 unsigned MBlazeInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
215 MachineBasicBlock::iterator I = MBB.end();
216 if (I == MBB.begin()) return 0;
218 while (I->isDebugValue()) {
219 if (I == MBB.begin())
224 if (!MBlaze::isUncondBranchOpcode(I->getOpcode()) &&
225 !MBlaze::isCondBranchOpcode(I->getOpcode()))
228 // Remove the branch.
229 I->eraseFromParent();
233 if (I == MBB.begin()) return 1;
235 if (!MBlaze::isCondBranchOpcode(I->getOpcode()))
238 // Remove the branch.
239 I->eraseFromParent();
243 bool 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;
274 /// 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.
278 unsigned MBlazeInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
279 MBlazeFunctionInfo *MBlazeFI = MF->getInfo<MBlazeFunctionInfo>();
280 unsigned GlobalBaseReg = MBlazeFI->getGlobalBaseReg();
281 if (GlobalBaseReg != 0)
282 return GlobalBaseReg;
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();
290 GlobalBaseReg = RegInfo.createVirtualRegister(MBlaze::GPRRegisterClass);
291 BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY),
292 GlobalBaseReg).addReg(MBlaze::R20);
293 RegInfo.addLiveIn(MBlaze::R20);
295 MBlazeFI->setGlobalBaseReg(GlobalBaseReg);
296 return GlobalBaseReg;
299 MCInstrInfo *createMBlazeMCInstrInfo() {
300 MCInstrInfo *X = new MCInstrInfo();
301 InitMBlazeMCInstrInfo(X);
305 extern "C" void LLVMInitializeMBlazeMCInstrInfo() {
306 TargetRegistry::RegisterMCInstrInfo(TheMBlazeTarget, createMBlazeMCInstrInfo);