blob: 598cf2a68c6bd14d56995b4a11f36346e0da24f4 [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
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000031/// 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.
36unsigned 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.
58unsigned 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
75unsigned BlackfinInstrInfo::
76InsertBranch(MachineBasicBlock &MBB,
77 MachineBasicBlock *TBB,
78 MachineBasicBlock *FBB,
Stuart Hastings3bf91252010-06-17 22:43:56 +000079 const SmallVectorImpl<MachineOperand> &Cond,
80 DebugLoc DL) const {
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000081 // 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!");
Chris Lattnerc7f3ace2010-04-02 20:16:16 +000089 BuildMI(&MBB, DL, get(BF::JUMPa)).addMBB(TBB);
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000090 return 1;
91 }
92
93 // Conditional branch.
94 llvm_unreachable("Implement conditional branches!");
95}
96
Jakob Stoklund Olesen629d8072010-07-11 05:44:34 +000097void 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
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000157static bool inClass(const TargetRegisterClass &Test,
158 unsigned Reg,
159 const TargetRegisterClass *RC) {
160 if (TargetRegisterInfo::isPhysicalRegister(Reg))
161 return Test.contains(Reg);
162 else
Jakob Stoklund Olesenfa226bc2011-06-02 05:43:46 +0000163 return Test.hasSubClassEq(RC);
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000164}
165
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000166void
167BlackfinInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
168 MachineBasicBlock::iterator I,
169 unsigned SrcReg,
170 bool isKill,
171 int FI,
Evan Cheng746ad692010-05-06 19:06:44 +0000172 const TargetRegisterClass *RC,
173 const TargetRegisterInfo *TRI) const {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000174 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000175
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
204void BlackfinInstrInfo::
205storeRegToAddr(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
214void
215BlackfinInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
216 MachineBasicBlock::iterator I,
217 unsigned DestReg,
218 int FI,
Evan Cheng746ad692010-05-06 19:06:44 +0000219 const TargetRegisterClass *RC,
220 const TargetRegisterInfo *TRI) const {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000221 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000222 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
246void BlackfinInstrInfo::
247loadRegFromAddr(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}