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