- Eliminate MCCodeEmitter's dependency on TargetMachine. It now uses MCInstrInfo
[oota-llvm.git] / lib / Target / MBlaze / MBlazeInstrInfo.cpp
1 //===- 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"
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"
24
25 #define GET_INSTRINFO_CTOR
26 #define GET_INSTRINFO_MC_DESC
27 #include "MBlazeGenInstrInfo.inc"
28
29 using namespace llvm;
30
31 MBlazeInstrInfo::MBlazeInstrInfo(MBlazeTargetMachine &tm)
32   : MBlazeGenInstrInfo(MBlaze::ADJCALLSTACKDOWN, MBlaze::ADJCALLSTACKUP),
33     TM(tm), RI(*TM.getSubtargetImpl(), *this) {}
34
35 static bool isZeroImm(const MachineOperand &op) {
36   return op.isImm() && op.getImm() == 0;
37 }
38
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();
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.
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();
71     }
72   }
73   return 0;
74 }
75
76 /// insertNoop - If data hazard condition is found insert the target nop
77 /// instruction.
78 void MBlazeInstrInfo::
79 insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const {
80   DebugLoc DL;
81   BuildMI(MBB, MI, DL, get(MBlaze::NOP));
82 }
83
84 void MBlazeInstrInfo::
85 copyPhysReg(MachineBasicBlock &MBB,
86             MachineBasicBlock::iterator I, DebugLoc DL,
87             unsigned DestReg, unsigned SrcReg,
88             bool KillSrc) const {
89   llvm::BuildMI(MBB, I, DL, get(MBlaze::ADDK), DestReg)
90     .addReg(SrcReg, getKillRegState(KillSrc)).addReg(MBlaze::R0);
91 }
92
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 {
98   DebugLoc DL;
99   BuildMI(MBB, I, DL, get(MBlaze::SWI)).addReg(SrcReg,getKillRegState(isKill))
100     .addFrameIndex(FI).addImm(0); //.addFrameIndex(FI);
101 }
102
103 void MBlazeInstrInfo::
104 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
105                      unsigned DestReg, int FI,
106                      const TargetRegisterClass *RC,
107                      const TargetRegisterInfo *TRI) const {
108   DebugLoc DL;
109   BuildMI(MBB, I, DL, get(MBlaze::LWI), DestReg)
110       .addFrameIndex(FI).addImm(0); //.addFrameIndex(FI);
111 }
112
113 //===----------------------------------------------------------------------===//
114 // Branch Analysis
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())
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
187 unsigned MBlazeInstrInfo::
188 InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
189              MachineBasicBlock *FBB,
190              const SmallVectorImpl<MachineOperand> &Cond,
191              DebugLoc DL) const {
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!");
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;
212 }
213
214 unsigned 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
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;
271   }
272 }
273
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.
277 ///
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;
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
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);
294
295   MBlazeFI->setGlobalBaseReg(GlobalBaseReg);
296   return GlobalBaseReg;
297 }
298
299 MCInstrInfo *createMBlazeMCInstrInfo() {
300   MCInstrInfo *X = new MCInstrInfo();
301   InitMBlazeMCInstrInfo(X);
302   return X;
303 }
304
305 extern "C" void LLVMInitializeMBlazeMCInstrInfo() {
306   TargetRegistry::RegisterMCInstrInfo(TheMBlazeTarget, createMBlazeMCInstrInfo);
307 }