blob: 230fad3e94e19afd2492a6e03512711e492cc081 [file] [log] [blame]
Jakob Stoklund Olesend9509412009-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,
Stuart Hastings3bf91252010-06-17 22:43:56 +0000107 const SmallVectorImpl<MachineOperand> &Cond,
108 DebugLoc DL) const {
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000109 // Shouldn't be a fall through.
110 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
111 assert((Cond.size() == 1 || Cond.size() == 0) &&
112 "Branch conditions have one component!");
113
114 if (Cond.empty()) {
115 // Unconditional branch?
116 assert(!FBB && "Unconditional branch with multiple successors!");
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000117 BuildMI(&MBB, DL, get(BF::JUMPa)).addMBB(TBB);
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000118 return 1;
119 }
120
121 // Conditional branch.
122 llvm_unreachable("Implement conditional branches!");
123}
124
125static bool inClass(const TargetRegisterClass &Test,
126 unsigned Reg,
127 const TargetRegisterClass *RC) {
128 if (TargetRegisterInfo::isPhysicalRegister(Reg))
129 return Test.contains(Reg);
130 else
131 return &Test==RC || Test.hasSubClass(RC);
132}
133
134bool BlackfinInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
135 MachineBasicBlock::iterator I,
136 unsigned DestReg,
137 unsigned SrcReg,
138 const TargetRegisterClass *DestRC,
Dan Gohman34dcc6f2010-05-06 20:33:48 +0000139 const TargetRegisterClass *SrcRC,
140 DebugLoc DL) const {
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000141 if (inClass(BF::ALLRegClass, DestReg, DestRC) &&
142 inClass(BF::ALLRegClass, SrcReg, SrcRC)) {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000143 BuildMI(MBB, I, DL, get(BF::MOVE), DestReg).addReg(SrcReg);
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000144 return true;
145 }
146
147 if (inClass(BF::D16RegClass, DestReg, DestRC) &&
148 inClass(BF::D16RegClass, SrcReg, SrcRC)) {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000149 BuildMI(MBB, I, DL, get(BF::SLL16i), DestReg).addReg(SrcReg).addImm(0);
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000150 return true;
151 }
152
153 if (inClass(BF::AnyCCRegClass, SrcReg, SrcRC) &&
154 inClass(BF::DRegClass, DestReg, DestRC)) {
155 if (inClass(BF::NotCCRegClass, SrcReg, SrcRC)) {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000156 BuildMI(MBB, I, DL, get(BF::MOVENCC_z), DestReg).addReg(SrcReg);
157 BuildMI(MBB, I, DL, get(BF::BITTGL), DestReg).addReg(DestReg).addImm(0);
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000158 } else {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000159 BuildMI(MBB, I, DL, get(BF::MOVECC_zext), DestReg).addReg(SrcReg);
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000160 }
161 return true;
162 }
163
164 if (inClass(BF::AnyCCRegClass, DestReg, DestRC) &&
165 inClass(BF::DRegClass, SrcReg, SrcRC)) {
166 if (inClass(BF::NotCCRegClass, DestReg, DestRC))
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000167 BuildMI(MBB, I, DL, get(BF::SETEQri_not), DestReg).addReg(SrcReg);
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000168 else
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000169 BuildMI(MBB, I, DL, get(BF::MOVECC_nz), DestReg).addReg(SrcReg);
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000170 return true;
171 }
172
173 if (inClass(BF::NotCCRegClass, DestReg, DestRC) &&
174 inClass(BF::JustCCRegClass, SrcReg, SrcRC)) {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000175 BuildMI(MBB, I, DL, get(BF::MOVE_ncccc), DestReg).addReg(SrcReg);
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000176 return true;
177 }
178
179 if (inClass(BF::JustCCRegClass, DestReg, DestRC) &&
180 inClass(BF::NotCCRegClass, SrcReg, SrcRC)) {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000181 BuildMI(MBB, I, DL, get(BF::MOVE_ccncc), DestReg).addReg(SrcReg);
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000182 return true;
183 }
184
185 llvm_unreachable((std::string("Bad regclasses for reg-to-reg copy: ")+
186 SrcRC->getName() + " -> " + DestRC->getName()).c_str());
187 return false;
188}
189
190void
191BlackfinInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
192 MachineBasicBlock::iterator I,
193 unsigned SrcReg,
194 bool isKill,
195 int FI,
Evan Cheng746ad692010-05-06 19:06:44 +0000196 const TargetRegisterClass *RC,
197 const TargetRegisterInfo *TRI) const {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000198 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000199
200 if (inClass(BF::DPRegClass, SrcReg, RC)) {
201 BuildMI(MBB, I, DL, get(BF::STORE32fi))
202 .addReg(SrcReg, getKillRegState(isKill))
203 .addFrameIndex(FI)
204 .addImm(0);
205 return;
206 }
207
208 if (inClass(BF::D16RegClass, SrcReg, RC)) {
209 BuildMI(MBB, I, DL, get(BF::STORE16fi))
210 .addReg(SrcReg, getKillRegState(isKill))
211 .addFrameIndex(FI)
212 .addImm(0);
213 return;
214 }
215
216 if (inClass(BF::AnyCCRegClass, SrcReg, RC)) {
217 BuildMI(MBB, I, DL, get(BF::STORE8fi))
218 .addReg(SrcReg, getKillRegState(isKill))
219 .addFrameIndex(FI)
220 .addImm(0);
221 return;
222 }
223
224 llvm_unreachable((std::string("Cannot store regclass to stack slot: ")+
225 RC->getName()).c_str());
226}
227
228void BlackfinInstrInfo::
229storeRegToAddr(MachineFunction &MF,
230 unsigned SrcReg,
231 bool isKill,
232 SmallVectorImpl<MachineOperand> &Addr,
233 const TargetRegisterClass *RC,
234 SmallVectorImpl<MachineInstr*> &NewMIs) const {
235 llvm_unreachable("storeRegToAddr not implemented");
236}
237
238void
239BlackfinInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
240 MachineBasicBlock::iterator I,
241 unsigned DestReg,
242 int FI,
Evan Cheng746ad692010-05-06 19:06:44 +0000243 const TargetRegisterClass *RC,
244 const TargetRegisterInfo *TRI) const {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000245 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000246 if (inClass(BF::DPRegClass, DestReg, RC)) {
247 BuildMI(MBB, I, DL, get(BF::LOAD32fi), DestReg)
248 .addFrameIndex(FI)
249 .addImm(0);
250 return;
251 }
252
253 if (inClass(BF::D16RegClass, DestReg, RC)) {
254 BuildMI(MBB, I, DL, get(BF::LOAD16fi), DestReg)
255 .addFrameIndex(FI)
256 .addImm(0);
257 return;
258 }
259
260 if (inClass(BF::AnyCCRegClass, DestReg, RC)) {
261 BuildMI(MBB, I, DL, get(BF::LOAD8fi), DestReg)
262 .addFrameIndex(FI)
263 .addImm(0);
264 return;
265 }
266
267 llvm_unreachable("Cannot load regclass from stack slot");
268}
269
270void BlackfinInstrInfo::
271loadRegFromAddr(MachineFunction &MF,
272 unsigned DestReg,
273 SmallVectorImpl<MachineOperand> &Addr,
274 const TargetRegisterClass *RC,
275 SmallVectorImpl<MachineInstr*> &NewMIs) const {
276 llvm_unreachable("loadRegFromAddr not implemented");
277}