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
27using namespace llvm;
28
29BlackfinInstrInfo::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.
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,
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
100void 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
160static 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
169void
170BlackfinInstrInfo::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
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,
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
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}
257