blob: 3fd5d4dc0bf1f5937f0c41a0c6d0536ff4d1b8a9 [file] [log] [blame]
Jakob Stoklund Olesen2cfddbb2009-08-02 17:32:10 +00001//===- 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
24using namespace llvm;
25
26BlackfinInstrInfo::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.
33bool 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.
64unsigned 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.
86unsigned 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
103unsigned BlackfinInstrInfo::
104InsertBranch(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 = DebugLoc::getUnknownLoc();
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
127static 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
136bool BlackfinInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
137 MachineBasicBlock::iterator I,
138 unsigned DestReg,
139 unsigned SrcReg,
140 const TargetRegisterClass *DestRC,
141 const TargetRegisterClass *SrcRC) const {
142 DebugLoc dl = DebugLoc::getUnknownLoc();
143
144 if (inClass(BF::ALLRegClass, DestReg, DestRC) &&
145 inClass(BF::ALLRegClass, SrcReg, SrcRC)) {
146 BuildMI(MBB, I, dl, get(BF::MOVE), DestReg).addReg(SrcReg);
147 return true;
148 }
149
150 if (inClass(BF::D16RegClass, DestReg, DestRC) &&
151 inClass(BF::D16RegClass, SrcReg, SrcRC)) {
152 BuildMI(MBB, I, dl, get(BF::SLL16i), DestReg).addReg(SrcReg).addImm(0);
153 return true;
154 }
155
156 if (inClass(BF::AnyCCRegClass, SrcReg, SrcRC) &&
157 inClass(BF::DRegClass, DestReg, DestRC)) {
158 if (inClass(BF::NotCCRegClass, SrcReg, SrcRC)) {
159 BuildMI(MBB, I, dl, get(BF::MOVENCC_z), DestReg).addReg(SrcReg);
160 BuildMI(MBB, I, dl, get(BF::BITTGL), DestReg).addReg(DestReg).addImm(0);
161 } else {
162 BuildMI(MBB, I, dl, get(BF::MOVECC_zext), DestReg).addReg(SrcReg);
163 }
164 return true;
165 }
166
167 if (inClass(BF::AnyCCRegClass, DestReg, DestRC) &&
168 inClass(BF::DRegClass, SrcReg, SrcRC)) {
169 if (inClass(BF::NotCCRegClass, DestReg, DestRC))
170 BuildMI(MBB, I, dl, get(BF::SETEQri_not), DestReg).addReg(SrcReg);
171 else
172 BuildMI(MBB, I, dl, get(BF::MOVECC_nz), DestReg).addReg(SrcReg);
173 return true;
174 }
175
176 if (inClass(BF::NotCCRegClass, DestReg, DestRC) &&
177 inClass(BF::JustCCRegClass, SrcReg, SrcRC)) {
178 BuildMI(MBB, I, dl, get(BF::MOVE_ncccc), DestReg).addReg(SrcReg);
179 return true;
180 }
181
182 if (inClass(BF::JustCCRegClass, DestReg, DestRC) &&
183 inClass(BF::NotCCRegClass, SrcReg, SrcRC)) {
184 BuildMI(MBB, I, dl, get(BF::MOVE_ccncc), DestReg).addReg(SrcReg);
185 return true;
186 }
187
188 llvm_unreachable((std::string("Bad regclasses for reg-to-reg copy: ")+
189 SrcRC->getName() + " -> " + DestRC->getName()).c_str());
190 return false;
191}
192
193void
194BlackfinInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
195 MachineBasicBlock::iterator I,
196 unsigned SrcReg,
197 bool isKill,
198 int FI,
199 const TargetRegisterClass *RC) const {
200 DebugLoc DL = I != MBB.end() ?
201 I->getDebugLoc() : DebugLoc::getUnknownLoc();
202
203 if (inClass(BF::DPRegClass, SrcReg, RC)) {
204 BuildMI(MBB, I, DL, get(BF::STORE32fi))
205 .addReg(SrcReg, getKillRegState(isKill))
206 .addFrameIndex(FI)
207 .addImm(0);
208 return;
209 }
210
211 if (inClass(BF::D16RegClass, SrcReg, RC)) {
212 BuildMI(MBB, I, DL, get(BF::STORE16fi))
213 .addReg(SrcReg, getKillRegState(isKill))
214 .addFrameIndex(FI)
215 .addImm(0);
216 return;
217 }
218
219 if (inClass(BF::AnyCCRegClass, SrcReg, RC)) {
220 BuildMI(MBB, I, DL, get(BF::STORE8fi))
221 .addReg(SrcReg, getKillRegState(isKill))
222 .addFrameIndex(FI)
223 .addImm(0);
224 return;
225 }
226
227 llvm_unreachable((std::string("Cannot store regclass to stack slot: ")+
228 RC->getName()).c_str());
229}
230
231void BlackfinInstrInfo::
232storeRegToAddr(MachineFunction &MF,
233 unsigned SrcReg,
234 bool isKill,
235 SmallVectorImpl<MachineOperand> &Addr,
236 const TargetRegisterClass *RC,
237 SmallVectorImpl<MachineInstr*> &NewMIs) const {
238 llvm_unreachable("storeRegToAddr not implemented");
239}
240
241void
242BlackfinInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
243 MachineBasicBlock::iterator I,
244 unsigned DestReg,
245 int FI,
246 const TargetRegisterClass *RC) const {
247 DebugLoc DL = I != MBB.end() ?
248 I->getDebugLoc() : DebugLoc::getUnknownLoc();
249 if (inClass(BF::DPRegClass, DestReg, RC)) {
250 BuildMI(MBB, I, DL, get(BF::LOAD32fi), DestReg)
251 .addFrameIndex(FI)
252 .addImm(0);
253 return;
254 }
255
256 if (inClass(BF::D16RegClass, DestReg, RC)) {
257 BuildMI(MBB, I, DL, get(BF::LOAD16fi), DestReg)
258 .addFrameIndex(FI)
259 .addImm(0);
260 return;
261 }
262
263 if (inClass(BF::AnyCCRegClass, DestReg, RC)) {
264 BuildMI(MBB, I, DL, get(BF::LOAD8fi), DestReg)
265 .addFrameIndex(FI)
266 .addImm(0);
267 return;
268 }
269
270 llvm_unreachable("Cannot load regclass from stack slot");
271}
272
273void BlackfinInstrInfo::
274loadRegFromAddr(MachineFunction &MF,
275 unsigned DestReg,
276 SmallVectorImpl<MachineOperand> &Addr,
277 const TargetRegisterClass *RC,
278 SmallVectorImpl<MachineInstr*> &NewMIs) const {
279 llvm_unreachable("loadRegFromAddr not implemented");
280}