SparcInstrInfo.cpp revision 78e6e009223a38739797629ca2d217acf86dda93
1//===- SparcInstrInfo.cpp - Sparc 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 Sparc implementation of the TargetInstrInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SparcInstrInfo.h"
15#include "SparcSubtarget.h"
16#include "Sparc.h"
17#include "llvm/ADT/STLExtras.h"
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/CodeGen/MachineInstrBuilder.h"
20#include "llvm/CodeGen/MachineRegisterInfo.h"
21#include "llvm/Support/ErrorHandling.h"
22#include "SparcGenInstrInfo.inc"
23#include "SparcMachineFunctionInfo.h"
24using namespace llvm;
25
26SparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST)
27  : TargetInstrInfoImpl(SparcInsts, array_lengthof(SparcInsts)),
28    RI(ST, *this), Subtarget(ST) {
29}
30
31/// isLoadFromStackSlot - If the specified machine instruction is a direct
32/// load from a stack slot, return the virtual or physical register number of
33/// the destination along with the FrameIndex of the loaded stack slot.  If
34/// not, return 0.  This predicate must return 0 if the instruction has
35/// any side effects other than loading from the stack slot.
36unsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
37                                             int &FrameIndex) const {
38  if (MI->getOpcode() == SP::LDri ||
39      MI->getOpcode() == SP::LDFri ||
40      MI->getOpcode() == SP::LDDFri) {
41    if (MI->getOperand(1).isFI() && MI->getOperand(2).isImm() &&
42        MI->getOperand(2).getImm() == 0) {
43      FrameIndex = MI->getOperand(1).getIndex();
44      return MI->getOperand(0).getReg();
45    }
46  }
47  return 0;
48}
49
50/// isStoreToStackSlot - If the specified machine instruction is a direct
51/// store to a stack slot, return the virtual or physical register number of
52/// the source reg along with the FrameIndex of the loaded stack slot.  If
53/// not, return 0.  This predicate must return 0 if the instruction has
54/// any side effects other than storing to the stack slot.
55unsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
56                                            int &FrameIndex) const {
57  if (MI->getOpcode() == SP::STri ||
58      MI->getOpcode() == SP::STFri ||
59      MI->getOpcode() == SP::STDFri) {
60    if (MI->getOperand(0).isFI() && MI->getOperand(1).isImm() &&
61        MI->getOperand(1).getImm() == 0) {
62      FrameIndex = MI->getOperand(0).getIndex();
63      return MI->getOperand(2).getReg();
64    }
65  }
66  return 0;
67}
68
69unsigned
70SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
71                             MachineBasicBlock *FBB,
72                             const SmallVectorImpl<MachineOperand> &Cond,
73                             DebugLoc DL)const{
74  // Can only insert uncond branches so far.
75  assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!");
76  BuildMI(&MBB, DL, get(SP::BA)).addMBB(TBB);
77  return 1;
78}
79
80void SparcInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
81                                 MachineBasicBlock::iterator I, DebugLoc DL,
82                                 unsigned DestReg, unsigned SrcReg,
83                                 bool KillSrc) const {
84  if (SP::IntRegsRegClass.contains(DestReg, SrcReg))
85    BuildMI(MBB, I, DL, get(SP::ORrr), DestReg).addReg(SP::G0)
86      .addReg(SrcReg, getKillRegState(KillSrc));
87  else if (SP::FPRegsRegClass.contains(DestReg, SrcReg))
88    BuildMI(MBB, I, DL, get(SP::FMOVS), DestReg)
89      .addReg(SrcReg, getKillRegState(KillSrc));
90  else if (SP::DFPRegsRegClass.contains(DestReg, SrcReg))
91    BuildMI(MBB, I, DL, get(Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD), DestReg)
92      .addReg(SrcReg, getKillRegState(KillSrc));
93  else
94    llvm_unreachable("Impossible reg-to-reg copy");
95}
96
97void SparcInstrInfo::
98storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
99                    unsigned SrcReg, bool isKill, int FI,
100                    const TargetRegisterClass *RC,
101                    const TargetRegisterInfo *TRI) const {
102  DebugLoc DL;
103  if (I != MBB.end()) DL = I->getDebugLoc();
104
105  // On the order of operands here: think "[FrameIdx + 0] = SrcReg".
106  if (RC == SP::IntRegsRegisterClass)
107    BuildMI(MBB, I, DL, get(SP::STri)).addFrameIndex(FI).addImm(0)
108      .addReg(SrcReg, getKillRegState(isKill));
109  else if (RC == SP::FPRegsRegisterClass)
110    BuildMI(MBB, I, DL, get(SP::STFri)).addFrameIndex(FI).addImm(0)
111      .addReg(SrcReg,  getKillRegState(isKill));
112  else if (RC == SP::DFPRegsRegisterClass)
113    BuildMI(MBB, I, DL, get(SP::STDFri)).addFrameIndex(FI).addImm(0)
114      .addReg(SrcReg,  getKillRegState(isKill));
115  else
116    llvm_unreachable("Can't store this register to stack slot");
117}
118
119void SparcInstrInfo::
120loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
121                     unsigned DestReg, int FI,
122                     const TargetRegisterClass *RC,
123                     const TargetRegisterInfo *TRI) const {
124  DebugLoc DL;
125  if (I != MBB.end()) DL = I->getDebugLoc();
126
127  if (RC == SP::IntRegsRegisterClass)
128    BuildMI(MBB, I, DL, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0);
129  else if (RC == SP::FPRegsRegisterClass)
130    BuildMI(MBB, I, DL, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0);
131  else if (RC == SP::DFPRegsRegisterClass)
132    BuildMI(MBB, I, DL, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0);
133  else
134    llvm_unreachable("Can't load this register from stack slot");
135}
136
137unsigned SparcInstrInfo::getGlobalBaseReg(MachineFunction *MF) const
138{
139  SparcMachineFunctionInfo *SparcFI = MF->getInfo<SparcMachineFunctionInfo>();
140  unsigned GlobalBaseReg = SparcFI->getGlobalBaseReg();
141  if (GlobalBaseReg != 0)
142    return GlobalBaseReg;
143
144  // Insert the set of GlobalBaseReg into the first MBB of the function
145  MachineBasicBlock &FirstMBB = MF->front();
146  MachineBasicBlock::iterator MBBI = FirstMBB.begin();
147  MachineRegisterInfo &RegInfo = MF->getRegInfo();
148
149  GlobalBaseReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
150
151
152  DebugLoc dl;
153
154  BuildMI(FirstMBB, MBBI, dl, get(SP::GETPCX), GlobalBaseReg);
155  SparcFI->setGlobalBaseReg(GlobalBaseReg);
156  return GlobalBaseReg;
157}
158