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