SparcInstrInfo.cpp revision c909950c384e8234a7b3c5a76b7f79e3f7012ceb
1//===-- SparcInstrInfo.cpp - Sparc Instruction Information ----------------===//
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 Sparc implementation of the TargetInstrInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SparcInstrInfo.h"
15#include "Sparc.h"
16#include "SparcMachineFunctionInfo.h"
17#include "SparcSubtarget.h"
18#include "llvm/CodeGen/MachineInstrBuilder.h"
19#include "llvm/CodeGen/MachineRegisterInfo.h"
20#include "llvm/Support/ErrorHandling.h"
21#include "llvm/Support/TargetRegistry.h"
22#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/SmallVector.h"
24
25#define GET_INSTRINFO_CTOR
26#include "SparcGenInstrInfo.inc"
27
28using namespace llvm;
29
30SparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST)
31  : SparcGenInstrInfo(SP::ADJCALLSTACKDOWN, SP::ADJCALLSTACKUP),
32    RI(ST, *this), Subtarget(ST) {
33}
34
35/// 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 SparcInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
41                                             int &FrameIndex) const {
42  if (MI->getOpcode() == SP::LDri ||
43      MI->getOpcode() == SP::LDFri ||
44      MI->getOpcode() == SP::LDDFri) {
45    if (MI->getOperand(1).isFI() && MI->getOperand(2).isImm() &&
46        MI->getOperand(2).getImm() == 0) {
47      FrameIndex = MI->getOperand(1).getIndex();
48      return MI->getOperand(0).getReg();
49    }
50  }
51  return 0;
52}
53
54/// isStoreToStackSlot - If the specified machine instruction is a direct
55/// store to a stack slot, return the virtual or physical register number of
56/// the source reg along with the FrameIndex of the loaded stack slot.  If
57/// not, return 0.  This predicate must return 0 if the instruction has
58/// any side effects other than storing to the stack slot.
59unsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
60                                            int &FrameIndex) const {
61  if (MI->getOpcode() == SP::STri ||
62      MI->getOpcode() == SP::STFri ||
63      MI->getOpcode() == SP::STDFri) {
64    if (MI->getOperand(0).isFI() && MI->getOperand(1).isImm() &&
65        MI->getOperand(1).getImm() == 0) {
66      FrameIndex = MI->getOperand(0).getIndex();
67      return MI->getOperand(2).getReg();
68    }
69  }
70  return 0;
71}
72
73static bool IsIntegerCC(unsigned CC)
74{
75  return  (CC <= SPCC::ICC_VC);
76}
77
78
79static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC)
80{
81  switch(CC) {
82  case SPCC::ICC_NE:   return SPCC::ICC_E;
83  case SPCC::ICC_E:    return SPCC::ICC_NE;
84  case SPCC::ICC_G:    return SPCC::ICC_LE;
85  case SPCC::ICC_LE:   return SPCC::ICC_G;
86  case SPCC::ICC_GE:   return SPCC::ICC_L;
87  case SPCC::ICC_L:    return SPCC::ICC_GE;
88  case SPCC::ICC_GU:   return SPCC::ICC_LEU;
89  case SPCC::ICC_LEU:  return SPCC::ICC_GU;
90  case SPCC::ICC_CC:   return SPCC::ICC_CS;
91  case SPCC::ICC_CS:   return SPCC::ICC_CC;
92  case SPCC::ICC_POS:  return SPCC::ICC_NEG;
93  case SPCC::ICC_NEG:  return SPCC::ICC_POS;
94  case SPCC::ICC_VC:   return SPCC::ICC_VS;
95  case SPCC::ICC_VS:   return SPCC::ICC_VC;
96
97  case SPCC::FCC_U:    return SPCC::FCC_O;
98  case SPCC::FCC_O:    return SPCC::FCC_U;
99  case SPCC::FCC_G:    return SPCC::FCC_LE;
100  case SPCC::FCC_LE:   return SPCC::FCC_G;
101  case SPCC::FCC_UG:   return SPCC::FCC_ULE;
102  case SPCC::FCC_ULE:  return SPCC::FCC_UG;
103  case SPCC::FCC_L:    return SPCC::FCC_GE;
104  case SPCC::FCC_GE:   return SPCC::FCC_L;
105  case SPCC::FCC_UL:   return SPCC::FCC_UGE;
106  case SPCC::FCC_UGE:  return SPCC::FCC_UL;
107  case SPCC::FCC_LG:   return SPCC::FCC_UE;
108  case SPCC::FCC_UE:   return SPCC::FCC_LG;
109  case SPCC::FCC_NE:   return SPCC::FCC_E;
110  case SPCC::FCC_E:    return SPCC::FCC_NE;
111  }
112  llvm_unreachable("Invalid cond code");
113}
114
115MachineInstr *
116SparcInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF,
117                                         int FrameIx,
118                                         uint64_t Offset,
119                                         const MDNode *MDPtr,
120                                         DebugLoc dl) const {
121  MachineInstrBuilder MIB = BuildMI(MF, dl, get(SP::DBG_VALUE))
122    .addFrameIndex(FrameIx).addImm(0).addImm(Offset).addMetadata(MDPtr);
123  return &*MIB;
124}
125
126
127bool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
128                                   MachineBasicBlock *&TBB,
129                                   MachineBasicBlock *&FBB,
130                                   SmallVectorImpl<MachineOperand> &Cond,
131                                   bool AllowModify) const
132{
133
134  MachineBasicBlock::iterator I = MBB.end();
135  MachineBasicBlock::iterator UnCondBrIter = MBB.end();
136  while (I != MBB.begin()) {
137    --I;
138
139    if (I->isDebugValue())
140      continue;
141
142    //When we see a non-terminator, we are done
143    if (!isUnpredicatedTerminator(I))
144      break;
145
146    //Terminator is not a branch
147    if (!I->isBranch())
148      return true;
149
150    //Handle Unconditional branches
151    if (I->getOpcode() == SP::BA) {
152      UnCondBrIter = I;
153
154      if (!AllowModify) {
155        TBB = I->getOperand(0).getMBB();
156        continue;
157      }
158
159      while (llvm::next(I) != MBB.end())
160        llvm::next(I)->eraseFromParent();
161
162      Cond.clear();
163      FBB = 0;
164
165      if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
166        TBB = 0;
167        I->eraseFromParent();
168        I = MBB.end();
169        UnCondBrIter = MBB.end();
170        continue;
171      }
172
173      TBB = I->getOperand(0).getMBB();
174      continue;
175    }
176
177    unsigned Opcode = I->getOpcode();
178    if (Opcode != SP::BCOND && Opcode != SP::FBCOND)
179      return true; //Unknown Opcode
180
181    SPCC::CondCodes BranchCode = (SPCC::CondCodes)I->getOperand(1).getImm();
182
183    if (Cond.empty()) {
184      MachineBasicBlock *TargetBB = I->getOperand(0).getMBB();
185      if (AllowModify && UnCondBrIter != MBB.end() &&
186          MBB.isLayoutSuccessor(TargetBB)) {
187
188        //Transform the code
189        //
190        //    brCC L1
191        //    ba L2
192        // L1:
193        //    ..
194        // L2:
195        //
196        // into
197        //
198        //   brnCC L2
199        // L1:
200        //   ...
201        // L2:
202        //
203        BranchCode = GetOppositeBranchCondition(BranchCode);
204        MachineBasicBlock::iterator OldInst = I;
205        BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(Opcode))
206          .addMBB(UnCondBrIter->getOperand(0).getMBB()).addImm(BranchCode);
207        BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(SP::BA))
208          .addMBB(TargetBB);
209
210        OldInst->eraseFromParent();
211        UnCondBrIter->eraseFromParent();
212
213        UnCondBrIter = MBB.end();
214        I = MBB.end();
215        continue;
216      }
217      FBB = TBB;
218      TBB = I->getOperand(0).getMBB();
219      Cond.push_back(MachineOperand::CreateImm(BranchCode));
220      continue;
221    }
222    //FIXME: Handle subsequent conditional branches
223    //For now, we can't handle multiple conditional branches
224    return true;
225  }
226  return false;
227}
228
229unsigned
230SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
231                             MachineBasicBlock *FBB,
232                             const SmallVectorImpl<MachineOperand> &Cond,
233                             DebugLoc DL) const {
234  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
235  assert((Cond.size() == 1 || Cond.size() == 0) &&
236         "Sparc branch conditions should have one component!");
237
238  if (Cond.empty()) {
239    assert(!FBB && "Unconditional branch with multiple successors!");
240    BuildMI(&MBB, DL, get(SP::BA)).addMBB(TBB);
241    return 1;
242  }
243
244  //Conditional branch
245  unsigned CC = Cond[0].getImm();
246
247  if (IsIntegerCC(CC))
248    BuildMI(&MBB, DL, get(SP::BCOND)).addMBB(TBB).addImm(CC);
249  else
250    BuildMI(&MBB, DL, get(SP::FBCOND)).addMBB(TBB).addImm(CC);
251  if (!FBB)
252    return 1;
253
254  BuildMI(&MBB, DL, get(SP::BA)).addMBB(FBB);
255  return 2;
256}
257
258unsigned SparcInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const
259{
260  MachineBasicBlock::iterator I = MBB.end();
261  unsigned Count = 0;
262  while (I != MBB.begin()) {
263    --I;
264
265    if (I->isDebugValue())
266      continue;
267
268    if (I->getOpcode() != SP::BA
269        && I->getOpcode() != SP::BCOND
270        && I->getOpcode() != SP::FBCOND)
271      break; // Not a branch
272
273    I->eraseFromParent();
274    I = MBB.end();
275    ++Count;
276  }
277  return Count;
278}
279
280void SparcInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
281                                 MachineBasicBlock::iterator I, DebugLoc DL,
282                                 unsigned DestReg, unsigned SrcReg,
283                                 bool KillSrc) const {
284  if (SP::IntRegsRegClass.contains(DestReg, SrcReg))
285    BuildMI(MBB, I, DL, get(SP::ORrr), DestReg).addReg(SP::G0)
286      .addReg(SrcReg, getKillRegState(KillSrc));
287  else if (SP::FPRegsRegClass.contains(DestReg, SrcReg))
288    BuildMI(MBB, I, DL, get(SP::FMOVS), DestReg)
289      .addReg(SrcReg, getKillRegState(KillSrc));
290  else if (SP::DFPRegsRegClass.contains(DestReg, SrcReg))
291    BuildMI(MBB, I, DL, get(Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD), DestReg)
292      .addReg(SrcReg, getKillRegState(KillSrc));
293  else
294    llvm_unreachable("Impossible reg-to-reg copy");
295}
296
297void SparcInstrInfo::
298storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
299                    unsigned SrcReg, bool isKill, int FI,
300                    const TargetRegisterClass *RC,
301                    const TargetRegisterInfo *TRI) const {
302  DebugLoc DL;
303  if (I != MBB.end()) DL = I->getDebugLoc();
304
305  // On the order of operands here: think "[FrameIdx + 0] = SrcReg".
306  if (RC == &SP::IntRegsRegClass)
307    BuildMI(MBB, I, DL, get(SP::STri)).addFrameIndex(FI).addImm(0)
308      .addReg(SrcReg, getKillRegState(isKill));
309  else if (RC == &SP::FPRegsRegClass)
310    BuildMI(MBB, I, DL, get(SP::STFri)).addFrameIndex(FI).addImm(0)
311      .addReg(SrcReg,  getKillRegState(isKill));
312  else if (RC == &SP::DFPRegsRegClass)
313    BuildMI(MBB, I, DL, get(SP::STDFri)).addFrameIndex(FI).addImm(0)
314      .addReg(SrcReg,  getKillRegState(isKill));
315  else
316    llvm_unreachable("Can't store this register to stack slot");
317}
318
319void SparcInstrInfo::
320loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
321                     unsigned DestReg, int FI,
322                     const TargetRegisterClass *RC,
323                     const TargetRegisterInfo *TRI) const {
324  DebugLoc DL;
325  if (I != MBB.end()) DL = I->getDebugLoc();
326
327  if (RC == &SP::IntRegsRegClass)
328    BuildMI(MBB, I, DL, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0);
329  else if (RC == &SP::FPRegsRegClass)
330    BuildMI(MBB, I, DL, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0);
331  else if (RC == &SP::DFPRegsRegClass)
332    BuildMI(MBB, I, DL, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0);
333  else
334    llvm_unreachable("Can't load this register from stack slot");
335}
336
337unsigned SparcInstrInfo::getGlobalBaseReg(MachineFunction *MF) const
338{
339  SparcMachineFunctionInfo *SparcFI = MF->getInfo<SparcMachineFunctionInfo>();
340  unsigned GlobalBaseReg = SparcFI->getGlobalBaseReg();
341  if (GlobalBaseReg != 0)
342    return GlobalBaseReg;
343
344  // Insert the set of GlobalBaseReg into the first MBB of the function
345  MachineBasicBlock &FirstMBB = MF->front();
346  MachineBasicBlock::iterator MBBI = FirstMBB.begin();
347  MachineRegisterInfo &RegInfo = MF->getRegInfo();
348
349  GlobalBaseReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
350
351
352  DebugLoc dl;
353
354  BuildMI(FirstMBB, MBBI, dl, get(SP::GETPCX), GlobalBaseReg);
355  SparcFI->setGlobalBaseReg(GlobalBaseReg);
356  return GlobalBaseReg;
357}
358