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
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 {
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() ? I->getDebugLoc() : DebugLoc();
202 if (inClass(BF::DPRegClass, SrcReg, RC)) {
203 BuildMI(MBB, I, DL, get(BF::STORE32fi))
204 .addReg(SrcReg, getKillRegState(isKill))
210 if (inClass(BF::D16RegClass, SrcReg, RC)) {
211 BuildMI(MBB, I, DL, get(BF::STORE16fi))
212 .addReg(SrcReg, getKillRegState(isKill))
218 if (inClass(BF::AnyCCRegClass, SrcReg, RC)) {
219 BuildMI(MBB, I, DL, get(BF::STORE8fi))
220 .addReg(SrcReg, getKillRegState(isKill))
226 llvm_unreachable((std::string("Cannot store regclass to stack slot: ")+
227 RC->getName()).c_str());
230 void BlackfinInstrInfo::
231 storeRegToAddr(MachineFunction &MF,
234 SmallVectorImpl<MachineOperand> &Addr,
235 const TargetRegisterClass *RC,
236 SmallVectorImpl<MachineInstr*> &NewMIs) const {
237 llvm_unreachable("storeRegToAddr not implemented");
241 BlackfinInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
242 MachineBasicBlock::iterator I,
245 const TargetRegisterClass *RC) const {
246 DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
247 if (inClass(BF::DPRegClass, DestReg, RC)) {
248 BuildMI(MBB, I, DL, get(BF::LOAD32fi), DestReg)
254 if (inClass(BF::D16RegClass, DestReg, RC)) {
255 BuildMI(MBB, I, DL, get(BF::LOAD16fi), DestReg)
261 if (inClass(BF::AnyCCRegClass, DestReg, RC)) {
262 BuildMI(MBB, I, DL, get(BF::LOAD8fi), DestReg)
268 llvm_unreachable("Cannot load regclass from stack slot");
271 void BlackfinInstrInfo::
272 loadRegFromAddr(MachineFunction &MF,
274 SmallVectorImpl<MachineOperand> &Addr,
275 const TargetRegisterClass *RC,
276 SmallVectorImpl<MachineInstr*> &NewMIs) const {
277 llvm_unreachable("loadRegFromAddr not implemented");