1 //===- BlackfinInstrInfo.cpp - Blackfin Instruction Information -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the Blackfin implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
14 #include "BlackfinInstrInfo.h"
15 #include "BlackfinSubtarget.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"
26 BlackfinInstrInfo::BlackfinInstrInfo(BlackfinSubtarget
&ST
)
27 : TargetInstrInfoImpl(BlackfinInsts
, array_lengthof(BlackfinInsts
)),
31 /// Return true if the instruction is a register to register move and
32 /// leave the source and dest operands in the passed parameters.
33 bool BlackfinInstrInfo::isMoveInstr(const MachineInstr
&MI
,
37 unsigned &DstSR
) const {
38 SrcSR
= DstSR
= 0; // No sub-registers.
39 switch (MI
.getOpcode()) {
45 DstReg
= MI
.getOperand(0).getReg();
46 SrcReg
= MI
.getOperand(1).getReg();
49 if (MI
.getOperand(2).getImm()!=0)
51 DstReg
= MI
.getOperand(0).getReg();
52 SrcReg
= MI
.getOperand(1).getReg();
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.
64 unsigned BlackfinInstrInfo::isLoadFromStackSlot(const MachineInstr
*MI
,
65 int &FrameIndex
) const {
66 switch (MI
->getOpcode()) {
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();
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.
86 unsigned BlackfinInstrInfo::isStoreToStackSlot(const MachineInstr
*MI
,
87 int &FrameIndex
) const {
88 switch (MI
->getOpcode()) {
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();
103 unsigned BlackfinInstrInfo::
104 InsertBranch(MachineBasicBlock
&MBB
,
105 MachineBasicBlock
*TBB
,
106 MachineBasicBlock
*FBB
,
107 const SmallVectorImpl
<MachineOperand
> &Cond
) const {
108 // FIXME this should probably have a DebugLoc operand
109 DebugLoc dl
= DebugLoc::getUnknownLoc();
111 // Shouldn't be a fall through.
112 assert(TBB
&& "InsertBranch must not be told to insert a fallthrough");
113 assert((Cond
.size() == 1 || Cond
.size() == 0) &&
114 "Branch conditions have one component!");
117 // Unconditional branch?
118 assert(!FBB
&& "Unconditional branch with multiple successors!");
119 BuildMI(&MBB
, dl
, get(BF::JUMPa
)).addMBB(TBB
);
123 // Conditional branch.
124 llvm_unreachable("Implement conditional branches!");
127 static bool inClass(const TargetRegisterClass
&Test
,
129 const TargetRegisterClass
*RC
) {
130 if (TargetRegisterInfo::isPhysicalRegister(Reg
))
131 return Test
.contains(Reg
);
133 return &Test
==RC
|| Test
.hasSubClass(RC
);
136 bool BlackfinInstrInfo::copyRegToReg(MachineBasicBlock
&MBB
,
137 MachineBasicBlock::iterator I
,
140 const TargetRegisterClass
*DestRC
,
141 const TargetRegisterClass
*SrcRC
) const {
142 DebugLoc dl
= DebugLoc::getUnknownLoc();
144 if (inClass(BF::ALLRegClass
, DestReg
, DestRC
) &&
145 inClass(BF::ALLRegClass
, SrcReg
, SrcRC
)) {
146 BuildMI(MBB
, I
, dl
, get(BF::MOVE
), DestReg
).addReg(SrcReg
);
150 if (inClass(BF::D16RegClass
, DestReg
, DestRC
) &&
151 inClass(BF::D16RegClass
, SrcReg
, SrcRC
)) {
152 BuildMI(MBB
, I
, dl
, get(BF::SLL16i
), DestReg
).addReg(SrcReg
).addImm(0);
156 if (inClass(BF::AnyCCRegClass
, SrcReg
, SrcRC
) &&
157 inClass(BF::DRegClass
, DestReg
, DestRC
)) {
158 if (inClass(BF::NotCCRegClass
, SrcReg
, SrcRC
)) {
159 BuildMI(MBB
, I
, dl
, get(BF::MOVENCC_z
), DestReg
).addReg(SrcReg
);
160 BuildMI(MBB
, I
, dl
, get(BF::BITTGL
), DestReg
).addReg(DestReg
).addImm(0);
162 BuildMI(MBB
, I
, dl
, get(BF::MOVECC_zext
), DestReg
).addReg(SrcReg
);
167 if (inClass(BF::AnyCCRegClass
, DestReg
, DestRC
) &&
168 inClass(BF::DRegClass
, SrcReg
, SrcRC
)) {
169 if (inClass(BF::NotCCRegClass
, DestReg
, DestRC
))
170 BuildMI(MBB
, I
, dl
, get(BF::SETEQri_not
), DestReg
).addReg(SrcReg
);
172 BuildMI(MBB
, I
, dl
, get(BF::MOVECC_nz
), DestReg
).addReg(SrcReg
);
176 if (inClass(BF::NotCCRegClass
, DestReg
, DestRC
) &&
177 inClass(BF::JustCCRegClass
, SrcReg
, SrcRC
)) {
178 BuildMI(MBB
, I
, dl
, get(BF::MOVE_ncccc
), DestReg
).addReg(SrcReg
);
182 if (inClass(BF::JustCCRegClass
, DestReg
, DestRC
) &&
183 inClass(BF::NotCCRegClass
, SrcReg
, SrcRC
)) {
184 BuildMI(MBB
, I
, dl
, get(BF::MOVE_ccncc
), DestReg
).addReg(SrcReg
);
188 llvm_unreachable((std::string("Bad regclasses for reg-to-reg copy: ")+
189 SrcRC
->getName() + " -> " + DestRC
->getName()).c_str());
194 BlackfinInstrInfo::storeRegToStackSlot(MachineBasicBlock
&MBB
,
195 MachineBasicBlock::iterator I
,
199 const TargetRegisterClass
*RC
) const {
200 DebugLoc DL
= I
!= MBB
.end() ?
201 I
->getDebugLoc() : DebugLoc::getUnknownLoc();
203 if (inClass(BF::DPRegClass
, SrcReg
, RC
)) {
204 BuildMI(MBB
, I
, DL
, get(BF::STORE32fi
))
205 .addReg(SrcReg
, getKillRegState(isKill
))
211 if (inClass(BF::D16RegClass
, SrcReg
, RC
)) {
212 BuildMI(MBB
, I
, DL
, get(BF::STORE16fi
))
213 .addReg(SrcReg
, getKillRegState(isKill
))
219 if (inClass(BF::AnyCCRegClass
, SrcReg
, RC
)) {
220 BuildMI(MBB
, I
, DL
, get(BF::STORE8fi
))
221 .addReg(SrcReg
, getKillRegState(isKill
))
227 llvm_unreachable((std::string("Cannot store regclass to stack slot: ")+
228 RC
->getName()).c_str());
231 void BlackfinInstrInfo::
232 storeRegToAddr(MachineFunction
&MF
,
235 SmallVectorImpl
<MachineOperand
> &Addr
,
236 const TargetRegisterClass
*RC
,
237 SmallVectorImpl
<MachineInstr
*> &NewMIs
) const {
238 llvm_unreachable("storeRegToAddr not implemented");
242 BlackfinInstrInfo::loadRegFromStackSlot(MachineBasicBlock
&MBB
,
243 MachineBasicBlock::iterator I
,
246 const TargetRegisterClass
*RC
) const {
247 DebugLoc DL
= I
!= MBB
.end() ?
248 I
->getDebugLoc() : DebugLoc::getUnknownLoc();
249 if (inClass(BF::DPRegClass
, DestReg
, RC
)) {
250 BuildMI(MBB
, I
, DL
, get(BF::LOAD32fi
), DestReg
)
256 if (inClass(BF::D16RegClass
, DestReg
, RC
)) {
257 BuildMI(MBB
, I
, DL
, get(BF::LOAD16fi
), DestReg
)
263 if (inClass(BF::AnyCCRegClass
, DestReg
, RC
)) {
264 BuildMI(MBB
, I
, DL
, get(BF::LOAD8fi
), DestReg
)
270 llvm_unreachable("Cannot load regclass from stack slot");
273 void BlackfinInstrInfo::
274 loadRegFromAddr(MachineFunction
&MF
,
276 SmallVectorImpl
<MachineOperand
> &Addr
,
277 const TargetRegisterClass
*RC
,
278 SmallVectorImpl
<MachineInstr
*> &NewMIs
) const {
279 llvm_unreachable("loadRegFromAddr not implemented");