Add parsing for the Thumb t_addrmode_s4 addressing mode. This can almost
[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 /// isLoadFromStackSlot - If the specified machine instruction is a direct
32 /// load from a stack slot, return the virtual or physical register number of
33 /// the destination along with the FrameIndex of the loaded stack slot.  If
34 /// not, return 0.  This predicate must return 0 if the instruction has
35 /// any side effects other than loading from the stack slot.
36 unsigned BlackfinInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
37                                                 int &FrameIndex) const {
38   switch (MI->getOpcode()) {
39   default: break;
40   case BF::LOAD32fi:
41   case BF::LOAD16fi:
42     if (MI->getOperand(1).isFI() &&
43         MI->getOperand(2).isImm() &&
44         MI->getOperand(2).getImm() == 0) {
45       FrameIndex = MI->getOperand(1).getIndex();
46       return MI->getOperand(0).getReg();
47     }
48     break;
49   }
50   return 0;
51 }
52
53 /// isStoreToStackSlot - If the specified machine instruction is a direct
54 /// store to a stack slot, return the virtual or physical register number of
55 /// the source reg along with the FrameIndex of the loaded stack slot.  If
56 /// not, return 0.  This predicate must return 0 if the instruction has
57 /// any side effects other than storing to the stack slot.
58 unsigned BlackfinInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
59                                                int &FrameIndex) const {
60   switch (MI->getOpcode()) {
61   default: break;
62   case BF::STORE32fi:
63   case BF::STORE16fi:
64     if (MI->getOperand(1).isFI() &&
65         MI->getOperand(2).isImm() &&
66         MI->getOperand(2).getImm() == 0) {
67       FrameIndex = MI->getOperand(1).getIndex();
68       return MI->getOperand(0).getReg();
69     }
70     break;
71   }
72   return 0;
73 }
74
75 unsigned BlackfinInstrInfo::
76 InsertBranch(MachineBasicBlock &MBB,
77              MachineBasicBlock *TBB,
78              MachineBasicBlock *FBB,
79              const SmallVectorImpl<MachineOperand> &Cond,
80              DebugLoc DL) const {
81   // Shouldn't be a fall through.
82   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
83   assert((Cond.size() == 1 || Cond.size() == 0) &&
84          "Branch conditions have one component!");
85
86   if (Cond.empty()) {
87     // Unconditional branch?
88     assert(!FBB && "Unconditional branch with multiple successors!");
89     BuildMI(&MBB, DL, get(BF::JUMPa)).addMBB(TBB);
90     return 1;
91   }
92
93   // Conditional branch.
94   llvm_unreachable("Implement conditional branches!");
95 }
96
97 void BlackfinInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
98                                     MachineBasicBlock::iterator I, DebugLoc DL,
99                                     unsigned DestReg, unsigned SrcReg,
100                                     bool KillSrc) const {
101   if (BF::ALLRegClass.contains(DestReg, SrcReg)) {
102     BuildMI(MBB, I, DL, get(BF::MOVE), DestReg)
103       .addReg(SrcReg, getKillRegState(KillSrc));
104     return;
105   }
106
107   if (BF::D16RegClass.contains(DestReg, SrcReg)) {
108     BuildMI(MBB, I, DL, get(BF::SLL16i), DestReg)
109       .addReg(SrcReg, getKillRegState(KillSrc))
110       .addImm(0);
111     return;
112   }
113
114   if (BF::DRegClass.contains(DestReg)) {
115     if (SrcReg == BF::NCC) {
116       BuildMI(MBB, I, DL, get(BF::MOVENCC_z), DestReg)
117         .addReg(SrcReg, getKillRegState(KillSrc));
118       BuildMI(MBB, I, DL, get(BF::BITTGL), DestReg).addReg(DestReg).addImm(0);
119       return;
120     }
121     if (SrcReg == BF::CC) {
122       BuildMI(MBB, I, DL, get(BF::MOVECC_zext), DestReg)
123         .addReg(SrcReg, getKillRegState(KillSrc));
124       return;
125     }
126   }
127
128   if (BF::DRegClass.contains(SrcReg)) {
129     if (DestReg == BF::NCC) {
130       BuildMI(MBB, I, DL, get(BF::SETEQri_not), DestReg)
131         .addReg(SrcReg, getKillRegState(KillSrc)).addImm(0);
132       return;
133     }
134     if (DestReg == BF::CC) {
135       BuildMI(MBB, I, DL, get(BF::MOVECC_nz), DestReg)
136         .addReg(SrcReg, getKillRegState(KillSrc));
137       return;
138     }
139   }
140
141
142   if (DestReg == BF::NCC && SrcReg == BF::CC) {
143     BuildMI(MBB, I, DL, get(BF::MOVE_ncccc), DestReg)
144       .addReg(SrcReg, getKillRegState(KillSrc));
145     return;
146   }
147
148   if (DestReg == BF::CC && SrcReg == BF::NCC) {
149     BuildMI(MBB, I, DL, get(BF::MOVE_ccncc), DestReg)
150       .addReg(SrcReg, getKillRegState(KillSrc));
151     return;
152   }
153
154   llvm_unreachable("Bad reg-to-reg copy");
155 }
156
157 static bool inClass(const TargetRegisterClass &Test,
158                     unsigned Reg,
159                     const TargetRegisterClass *RC) {
160   if (TargetRegisterInfo::isPhysicalRegister(Reg))
161     return Test.contains(Reg);
162   else
163     return &Test==RC || Test.hasSubClass(RC);
164 }
165
166 void
167 BlackfinInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
168                                        MachineBasicBlock::iterator I,
169                                        unsigned SrcReg,
170                                        bool isKill,
171                                        int FI,
172                                        const TargetRegisterClass *RC,
173                                        const TargetRegisterInfo *TRI) const {
174   DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
175
176   if (inClass(BF::DPRegClass, SrcReg, RC)) {
177     BuildMI(MBB, I, DL, get(BF::STORE32fi))
178       .addReg(SrcReg, getKillRegState(isKill))
179       .addFrameIndex(FI)
180       .addImm(0);
181     return;
182   }
183
184   if (inClass(BF::D16RegClass, SrcReg, RC)) {
185     BuildMI(MBB, I, DL, get(BF::STORE16fi))
186       .addReg(SrcReg, getKillRegState(isKill))
187       .addFrameIndex(FI)
188       .addImm(0);
189     return;
190   }
191
192   if (inClass(BF::AnyCCRegClass, SrcReg, RC)) {
193     BuildMI(MBB, I, DL, get(BF::STORE8fi))
194       .addReg(SrcReg, getKillRegState(isKill))
195       .addFrameIndex(FI)
196       .addImm(0);
197     return;
198   }
199
200   llvm_unreachable((std::string("Cannot store regclass to stack slot: ")+
201                     RC->getName()).c_str());
202 }
203
204 void BlackfinInstrInfo::
205 storeRegToAddr(MachineFunction &MF,
206                unsigned SrcReg,
207                bool isKill,
208                SmallVectorImpl<MachineOperand> &Addr,
209                const TargetRegisterClass *RC,
210                SmallVectorImpl<MachineInstr*> &NewMIs) const {
211   llvm_unreachable("storeRegToAddr not implemented");
212 }
213
214 void
215 BlackfinInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
216                                         MachineBasicBlock::iterator I,
217                                         unsigned DestReg,
218                                         int FI,
219                                         const TargetRegisterClass *RC,
220                                         const TargetRegisterInfo *TRI) const {
221   DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
222   if (inClass(BF::DPRegClass, DestReg, RC)) {
223     BuildMI(MBB, I, DL, get(BF::LOAD32fi), DestReg)
224       .addFrameIndex(FI)
225       .addImm(0);
226     return;
227   }
228
229   if (inClass(BF::D16RegClass, DestReg, RC)) {
230     BuildMI(MBB, I, DL, get(BF::LOAD16fi), DestReg)
231       .addFrameIndex(FI)
232       .addImm(0);
233     return;
234   }
235
236   if (inClass(BF::AnyCCRegClass, DestReg, RC)) {
237     BuildMI(MBB, I, DL, get(BF::LOAD8fi), DestReg)
238       .addFrameIndex(FI)
239       .addImm(0);
240     return;
241   }
242
243   llvm_unreachable("Cannot load regclass from stack slot");
244 }
245
246 void BlackfinInstrInfo::
247 loadRegFromAddr(MachineFunction &MF,
248                 unsigned DestReg,
249                 SmallVectorImpl<MachineOperand> &Addr,
250                 const TargetRegisterClass *RC,
251                 SmallVectorImpl<MachineInstr*> &NewMIs) const {
252   llvm_unreachable("loadRegFromAddr not implemented");
253 }