• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- 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/CodeGen/MachineRegisterInfo.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/TargetRegistry.h"
23 
24 #define GET_INSTRINFO_CTOR
25 #include "BlackfinGenInstrInfo.inc"
26 
27 using namespace llvm;
28 
BlackfinInstrInfo(BlackfinSubtarget & ST)29 BlackfinInstrInfo::BlackfinInstrInfo(BlackfinSubtarget &ST)
30   : BlackfinGenInstrInfo(BF::ADJCALLSTACKDOWN, BF::ADJCALLSTACKUP),
31     RI(ST, *this),
32     Subtarget(ST) {}
33 
34 /// 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.
isLoadFromStackSlot(const MachineInstr * MI,int & FrameIndex) const39 unsigned 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.
isStoreToStackSlot(const MachineInstr * MI,int & FrameIndex) const61 unsigned 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 
78 unsigned BlackfinInstrInfo::
InsertBranch(MachineBasicBlock & MBB,MachineBasicBlock * TBB,MachineBasicBlock * FBB,const SmallVectorImpl<MachineOperand> & Cond,DebugLoc DL) const79 InsertBranch(MachineBasicBlock &MBB,
80              MachineBasicBlock *TBB,
81              MachineBasicBlock *FBB,
82              const SmallVectorImpl<MachineOperand> &Cond,
83              DebugLoc DL) const {
84   // 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!");
92     BuildMI(&MBB, DL, get(BF::JUMPa)).addMBB(TBB);
93     return 1;
94   }
95 
96   // Conditional branch.
97   llvm_unreachable("Implement conditional branches!");
98 }
99 
copyPhysReg(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,DebugLoc DL,unsigned DestReg,unsigned SrcReg,bool KillSrc) const100 void 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 
inClass(const TargetRegisterClass & Test,unsigned Reg,const TargetRegisterClass * RC)160 static bool inClass(const TargetRegisterClass &Test,
161                     unsigned Reg,
162                     const TargetRegisterClass *RC) {
163   if (TargetRegisterInfo::isPhysicalRegister(Reg))
164     return Test.contains(Reg);
165   else
166     return Test.hasSubClassEq(RC);
167 }
168 
169 void
storeRegToStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,unsigned SrcReg,bool isKill,int FI,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI) const170 BlackfinInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
171                                        MachineBasicBlock::iterator I,
172                                        unsigned SrcReg,
173                                        bool isKill,
174                                        int FI,
175                                        const TargetRegisterClass *RC,
176                                        const TargetRegisterInfo *TRI) const {
177   DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
178 
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 
207 void BlackfinInstrInfo::
storeRegToAddr(MachineFunction & MF,unsigned SrcReg,bool isKill,SmallVectorImpl<MachineOperand> & Addr,const TargetRegisterClass * RC,SmallVectorImpl<MachineInstr * > & NewMIs) const208 storeRegToAddr(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 
217 void
loadRegFromStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,unsigned DestReg,int FI,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI) const218 BlackfinInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
219                                         MachineBasicBlock::iterator I,
220                                         unsigned DestReg,
221                                         int FI,
222                                         const TargetRegisterClass *RC,
223                                         const TargetRegisterInfo *TRI) const {
224   DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
225   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 
249 void BlackfinInstrInfo::
loadRegFromAddr(MachineFunction & MF,unsigned DestReg,SmallVectorImpl<MachineOperand> & Addr,const TargetRegisterClass * RC,SmallVectorImpl<MachineInstr * > & NewMIs) const250 loadRegFromAddr(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 }
257