Add a DebugLoc argument to TargetInstrInfo::copyRegToReg, so that it
[oota-llvm.git] / lib / Target / Blackfin / BlackfinInstrInfo.cpp
1 //===- BlackfinInstrInfo.cpp - Blackfin 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 Blackfin implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "BlackfinInstrInfo.h"
15 #include "BlackfinSubtarget.h"
16 #include "Blackfin.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
20 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "BlackfinGenInstrInfo.inc"
23
24 using namespace llvm;
25
26 BlackfinInstrInfo::BlackfinInstrInfo(BlackfinSubtarget &ST)
27   : TargetInstrInfoImpl(BlackfinInsts, array_lengthof(BlackfinInsts)),
28     RI(ST, *this),
29     Subtarget(ST) {}
30
31 /// Return true if the instruction is a register to register move and
32 /// leave the source and dest operands in the passed parameters.
33 bool BlackfinInstrInfo::isMoveInstr(const MachineInstr &MI,
34                                     unsigned &SrcReg,
35                                     unsigned &DstReg,
36                                     unsigned &SrcSR,
37                                     unsigned &DstSR) const {
38   SrcSR = DstSR = 0; // No sub-registers.
39   switch (MI.getOpcode()) {
40   case BF::MOVE:
41   case BF::MOVE_ncccc:
42   case BF::MOVE_ccncc:
43   case BF::MOVECC_zext:
44   case BF::MOVECC_nz:
45     DstReg = MI.getOperand(0).getReg();
46     SrcReg = MI.getOperand(1).getReg();
47     return true;
48   case BF::SLL16i:
49     if (MI.getOperand(2).getImm()!=0)
50       return false;
51     DstReg = MI.getOperand(0).getReg();
52     SrcReg = MI.getOperand(1).getReg();
53     return true;
54   default:
55     return false;
56   }
57 }
58
59 /// isLoadFromStackSlot - If the specified machine instruction is a direct
60 /// load from a stack slot, return the virtual or physical register number of
61 /// the destination along with the FrameIndex of the loaded stack slot.  If
62 /// not, return 0.  This predicate must return 0 if the instruction has
63 /// any side effects other than loading from the stack slot.
64 unsigned BlackfinInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
65                                                 int &FrameIndex) const {
66   switch (MI->getOpcode()) {
67   default: break;
68   case BF::LOAD32fi:
69   case BF::LOAD16fi:
70     if (MI->getOperand(1).isFI() &&
71         MI->getOperand(2).isImm() &&
72         MI->getOperand(2).getImm() == 0) {
73       FrameIndex = MI->getOperand(1).getIndex();
74       return MI->getOperand(0).getReg();
75     }
76     break;
77   }
78   return 0;
79 }
80
81 /// isStoreToStackSlot - If the specified machine instruction is a direct
82 /// store to a stack slot, return the virtual or physical register number of
83 /// the source reg along with the FrameIndex of the loaded stack slot.  If
84 /// not, return 0.  This predicate must return 0 if the instruction has
85 /// any side effects other than storing to the stack slot.
86 unsigned BlackfinInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
87                                                int &FrameIndex) const {
88   switch (MI->getOpcode()) {
89   default: break;
90   case BF::STORE32fi:
91   case BF::STORE16fi:
92     if (MI->getOperand(1).isFI() &&
93         MI->getOperand(2).isImm() &&
94         MI->getOperand(2).getImm() == 0) {
95       FrameIndex = MI->getOperand(1).getIndex();
96       return MI->getOperand(0).getReg();
97     }
98     break;
99   }
100   return 0;
101 }
102
103 unsigned BlackfinInstrInfo::
104 InsertBranch(MachineBasicBlock &MBB,
105              MachineBasicBlock *TBB,
106              MachineBasicBlock *FBB,
107              const SmallVectorImpl<MachineOperand> &Cond) const {
108   // FIXME this should probably have a DebugLoc operand
109   DebugLoc DL;
110
111   // Shouldn't be a fall through.
112   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
113   assert((Cond.size() == 1 || Cond.size() == 0) &&
114          "Branch conditions have one component!");
115
116   if (Cond.empty()) {
117     // Unconditional branch?
118     assert(!FBB && "Unconditional branch with multiple successors!");
119     BuildMI(&MBB, DL, get(BF::JUMPa)).addMBB(TBB);
120     return 1;
121   }
122
123   // Conditional branch.
124   llvm_unreachable("Implement conditional branches!");
125 }
126
127 static bool inClass(const TargetRegisterClass &Test,
128                     unsigned Reg,
129                     const TargetRegisterClass *RC) {
130   if (TargetRegisterInfo::isPhysicalRegister(Reg))
131     return Test.contains(Reg);
132   else
133     return &Test==RC || Test.hasSubClass(RC);
134 }
135
136 bool BlackfinInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
137                                      MachineBasicBlock::iterator I,
138                                      unsigned DestReg,
139                                      unsigned SrcReg,
140                                      const TargetRegisterClass *DestRC,
141                                      const TargetRegisterClass *SrcRC,
142                                      DebugLoc DL) const {
143   if (inClass(BF::ALLRegClass, DestReg, DestRC) &&
144       inClass(BF::ALLRegClass, SrcReg,  SrcRC)) {
145     BuildMI(MBB, I, DL, get(BF::MOVE), DestReg).addReg(SrcReg);
146     return true;
147   }
148
149   if (inClass(BF::D16RegClass, DestReg, DestRC) &&
150       inClass(BF::D16RegClass, SrcReg,  SrcRC)) {
151     BuildMI(MBB, I, DL, get(BF::SLL16i), DestReg).addReg(SrcReg).addImm(0);
152     return true;
153   }
154
155   if (inClass(BF::AnyCCRegClass, SrcReg, SrcRC) &&
156       inClass(BF::DRegClass, DestReg, DestRC)) {
157     if (inClass(BF::NotCCRegClass, SrcReg, SrcRC)) {
158       BuildMI(MBB, I, DL, get(BF::MOVENCC_z), DestReg).addReg(SrcReg);
159       BuildMI(MBB, I, DL, get(BF::BITTGL), DestReg).addReg(DestReg).addImm(0);
160     } else {
161       BuildMI(MBB, I, DL, get(BF::MOVECC_zext), DestReg).addReg(SrcReg);
162     }
163     return true;
164   }
165
166   if (inClass(BF::AnyCCRegClass, DestReg, DestRC) &&
167       inClass(BF::DRegClass, SrcReg,  SrcRC)) {
168     if (inClass(BF::NotCCRegClass, DestReg, DestRC))
169       BuildMI(MBB, I, DL, get(BF::SETEQri_not), DestReg).addReg(SrcReg);
170     else
171       BuildMI(MBB, I, DL, get(BF::MOVECC_nz), DestReg).addReg(SrcReg);
172     return true;
173   }
174
175   if (inClass(BF::NotCCRegClass, DestReg, DestRC) &&
176       inClass(BF::JustCCRegClass, SrcReg,  SrcRC)) {
177     BuildMI(MBB, I, DL, get(BF::MOVE_ncccc), DestReg).addReg(SrcReg);
178     return true;
179   }
180
181   if (inClass(BF::JustCCRegClass, DestReg, DestRC) &&
182       inClass(BF::NotCCRegClass, SrcReg,  SrcRC)) {
183     BuildMI(MBB, I, DL, get(BF::MOVE_ccncc), DestReg).addReg(SrcReg);
184     return true;
185   }
186
187   llvm_unreachable((std::string("Bad regclasses for reg-to-reg copy: ")+
188                     SrcRC->getName() + " -> " + DestRC->getName()).c_str());
189   return false;
190 }
191
192 void
193 BlackfinInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
194                                        MachineBasicBlock::iterator I,
195                                        unsigned SrcReg,
196                                        bool isKill,
197                                        int FI,
198                                        const TargetRegisterClass *RC,
199                                        const TargetRegisterInfo *TRI) const {
200   DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
201
202   if (inClass(BF::DPRegClass, SrcReg, RC)) {
203     BuildMI(MBB, I, DL, get(BF::STORE32fi))
204       .addReg(SrcReg, getKillRegState(isKill))
205       .addFrameIndex(FI)
206       .addImm(0);
207     return;
208   }
209
210   if (inClass(BF::D16RegClass, SrcReg, RC)) {
211     BuildMI(MBB, I, DL, get(BF::STORE16fi))
212       .addReg(SrcReg, getKillRegState(isKill))
213       .addFrameIndex(FI)
214       .addImm(0);
215     return;
216   }
217
218   if (inClass(BF::AnyCCRegClass, SrcReg, RC)) {
219     BuildMI(MBB, I, DL, get(BF::STORE8fi))
220       .addReg(SrcReg, getKillRegState(isKill))
221       .addFrameIndex(FI)
222       .addImm(0);
223     return;
224   }
225
226   llvm_unreachable((std::string("Cannot store regclass to stack slot: ")+
227                     RC->getName()).c_str());
228 }
229
230 void BlackfinInstrInfo::
231 storeRegToAddr(MachineFunction &MF,
232                unsigned SrcReg,
233                bool isKill,
234                SmallVectorImpl<MachineOperand> &Addr,
235                const TargetRegisterClass *RC,
236                SmallVectorImpl<MachineInstr*> &NewMIs) const {
237   llvm_unreachable("storeRegToAddr not implemented");
238 }
239
240 void
241 BlackfinInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
242                                         MachineBasicBlock::iterator I,
243                                         unsigned DestReg,
244                                         int FI,
245                                         const TargetRegisterClass *RC,
246                                         const TargetRegisterInfo *TRI) const {
247   DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
248   if (inClass(BF::DPRegClass, DestReg, RC)) {
249     BuildMI(MBB, I, DL, get(BF::LOAD32fi), DestReg)
250       .addFrameIndex(FI)
251       .addImm(0);
252     return;
253   }
254
255   if (inClass(BF::D16RegClass, DestReg, RC)) {
256     BuildMI(MBB, I, DL, get(BF::LOAD16fi), DestReg)
257       .addFrameIndex(FI)
258       .addImm(0);
259     return;
260   }
261
262   if (inClass(BF::AnyCCRegClass, DestReg, RC)) {
263     BuildMI(MBB, I, DL, get(BF::LOAD8fi), DestReg)
264       .addFrameIndex(FI)
265       .addImm(0);
266     return;
267   }
268
269   llvm_unreachable("Cannot load regclass from stack slot");
270 }
271
272 void BlackfinInstrInfo::
273 loadRegFromAddr(MachineFunction &MF,
274                 unsigned DestReg,
275                 SmallVectorImpl<MachineOperand> &Addr,
276                 const TargetRegisterClass *RC,
277                 SmallVectorImpl<MachineInstr*> &NewMIs) const {
278   llvm_unreachable("loadRegFromAddr not implemented");
279 }