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