SparcInstrInfo.cpp revision 600f171486708734e2b9c9c617528cfc51c16850
16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//===- SparcInstrInfo.cpp - Sparc Instruction Information -------*- C++ -*-===//
26e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//
36e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
46e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//
56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source
66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// License. See LICENSE.TXT for details.
703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)//
86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//===----------------------------------------------------------------------===//
96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//
106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// This file contains the Sparc implementation of the TargetInstrInfo class.
116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//===----------------------------------------------------------------------===//
136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "SparcInstrInfo.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "SparcSubtarget.h"
166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "Sparc.h"
176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "llvm/ADT/STLExtras.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "llvm/ADT/SmallVector.h"
196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "llvm/CodeGen/MachineInstrBuilder.h"
206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "llvm/CodeGen/MachineRegisterInfo.h"
216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "llvm/Support/ErrorHandling.h"
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "SparcGenInstrInfo.inc"
236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "SparcMachineFunctionInfo.h"
246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)using namespace llvm;
256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)SparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST)
276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  : TargetInstrInfoImpl(SparcInsts, array_lengthof(SparcInsts)),
286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    RI(ST, *this), Subtarget(ST) {
296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)static bool isZeroImm(const MachineOperand &op) {
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return op.isImm() && op.getImm() == 0;
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// Return true if the instruction is a register to register move and
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// leave the source and dest operands in the passed parameters.
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci///
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool SparcInstrInfo::isMoveInstr(const MachineInstr &MI,
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 unsigned &SrcReg, unsigned &DstReg,
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 unsigned &SrcSR, unsigned &DstSR) const {
416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  SrcSR = DstSR = 0; // No sub-registers.
426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // We look for 3 kinds of patterns here:
446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // or with G0 or 0
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // add with G0 or 0
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // fmovs or FpMOVD (pseudo double move).
476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (MI.getOpcode() == SP::ORrr || MI.getOpcode() == SP::ADDrr) {
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (MI.getOperand(1).getReg() == SP::G0) {
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      DstReg = MI.getOperand(0).getReg();
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SrcReg = MI.getOperand(2).getReg();
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return true;
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (MI.getOperand(2).getReg() == SP::G0) {
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      DstReg = MI.getOperand(0).getReg();
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SrcReg = MI.getOperand(1).getReg();
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return true;
566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  } else if ((MI.getOpcode() == SP::ORri || MI.getOpcode() == SP::ADDri) &&
586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)             isZeroImm(MI.getOperand(2)) && MI.getOperand(1).isReg()) {
596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    DstReg = MI.getOperand(0).getReg();
606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    SrcReg = MI.getOperand(1).getReg();
616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return true;
626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  } else if (MI.getOpcode() == SP::FMOVS || MI.getOpcode() == SP::FpMOVD ||
636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)             MI.getOpcode() == SP::FMOVD) {
646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    SrcReg = MI.getOperand(1).getReg();
656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    DstReg = MI.getOperand(0).getReg();
666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return true;
676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return false;
696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// isLoadFromStackSlot - If the specified machine instruction is a direct
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// load from a stack slot, return the virtual or physical register number of
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// the destination along with the FrameIndex of the loaded stack slot.  If
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// not, return 0.  This predicate must return 0 if the instruction has
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// any side effects other than loading from the stack slot.
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciunsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                             int &FrameIndex) const {
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (MI->getOpcode() == SP::LDri ||
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      MI->getOpcode() == SP::LDFri ||
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      MI->getOpcode() == SP::LDDFri) {
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (MI->getOperand(1).isFI() && MI->getOperand(2).isImm() &&
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        MI->getOperand(2).getImm() == 0) {
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      FrameIndex = MI->getOperand(1).getIndex();
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return MI->getOperand(0).getReg();
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return 0;
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// isStoreToStackSlot - If the specified machine instruction is a direct
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// store to a stack slot, return the virtual or physical register number of
926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/// the source reg along with the FrameIndex of the loaded stack slot.  If
936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/// not, return 0.  This predicate must return 0 if the instruction has
946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/// any side effects other than storing to the stack slot.
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciunsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                            int &FrameIndex) const {
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (MI->getOpcode() == SP::STri ||
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      MI->getOpcode() == SP::STFri ||
996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      MI->getOpcode() == SP::STDFri) {
1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (MI->getOperand(0).isFI() && MI->getOperand(1).isImm() &&
1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        MI->getOperand(1).getImm() == 0) {
1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      FrameIndex = MI->getOperand(0).getIndex();
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return MI->getOperand(2).getReg();
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return 0;
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)unsigned
1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             MachineBasicBlock *FBB,
1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             const SmallVectorImpl<MachineOperand> &Cond,
1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             DebugLoc DL)const{
1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Can only insert uncond branches so far.
1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!");
1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  BuildMI(&MBB, DL, get(SP::BA)).addMBB(TBB);
1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return 1;
1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void SparcInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                 MachineBasicBlock::iterator I, DebugLoc DL,
1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                 unsigned DestReg, unsigned SrcReg,
1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                 bool KillSrc) const {
1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (SP::IntRegsRegClass.contains(DestReg, SrcReg))
1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    BuildMI(MBB, I, DL, get(SP::ORrr), DestReg).addReg(SP::G0)
1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      .addReg(SrcReg, getKillRegState(KillSrc));
1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  else if (SP::FPRegsRegClass.contains(DestReg, SrcReg))
1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    BuildMI(MBB, I, DL, get(SP::FMOVS), DestReg)
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      .addReg(SrcReg, getKillRegState(KillSrc));
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  else if (SP::DFPRegsRegClass.contains(DestReg, SrcReg))
1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    BuildMI(MBB, I, DL, get(Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD), DestReg)
1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      .addReg(SrcReg, getKillRegState(KillSrc));
1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  else
1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    llvm_unreachable("Impossible reg-to-reg copy");
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void SparcInstrInfo::
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                    unsigned SrcReg, bool isKill, int FI,
1406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                    const TargetRegisterClass *RC,
1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                    const TargetRegisterInfo *TRI) const {
1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DebugLoc DL;
1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (I != MBB.end()) DL = I->getDebugLoc();
1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
145  // On the order of operands here: think "[FrameIdx + 0] = SrcReg".
146  if (RC == SP::IntRegsRegisterClass)
147    BuildMI(MBB, I, DL, get(SP::STri)).addFrameIndex(FI).addImm(0)
148      .addReg(SrcReg, getKillRegState(isKill));
149  else if (RC == SP::FPRegsRegisterClass)
150    BuildMI(MBB, I, DL, get(SP::STFri)).addFrameIndex(FI).addImm(0)
151      .addReg(SrcReg,  getKillRegState(isKill));
152  else if (RC == SP::DFPRegsRegisterClass)
153    BuildMI(MBB, I, DL, get(SP::STDFri)).addFrameIndex(FI).addImm(0)
154      .addReg(SrcReg,  getKillRegState(isKill));
155  else
156    llvm_unreachable("Can't store this register to stack slot");
157}
158
159void SparcInstrInfo::
160loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
161                     unsigned DestReg, int FI,
162                     const TargetRegisterClass *RC,
163                     const TargetRegisterInfo *TRI) const {
164  DebugLoc DL;
165  if (I != MBB.end()) DL = I->getDebugLoc();
166
167  if (RC == SP::IntRegsRegisterClass)
168    BuildMI(MBB, I, DL, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0);
169  else if (RC == SP::FPRegsRegisterClass)
170    BuildMI(MBB, I, DL, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0);
171  else if (RC == SP::DFPRegsRegisterClass)
172    BuildMI(MBB, I, DL, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0);
173  else
174    llvm_unreachable("Can't load this register from stack slot");
175}
176
177unsigned SparcInstrInfo::getGlobalBaseReg(MachineFunction *MF) const
178{
179  SparcMachineFunctionInfo *SparcFI = MF->getInfo<SparcMachineFunctionInfo>();
180  unsigned GlobalBaseReg = SparcFI->getGlobalBaseReg();
181  if (GlobalBaseReg != 0)
182    return GlobalBaseReg;
183
184  // Insert the set of GlobalBaseReg into the first MBB of the function
185  MachineBasicBlock &FirstMBB = MF->front();
186  MachineBasicBlock::iterator MBBI = FirstMBB.begin();
187  MachineRegisterInfo &RegInfo = MF->getRegInfo();
188
189  GlobalBaseReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
190
191
192  DebugLoc dl;
193
194  BuildMI(FirstMBB, MBBI, dl, get(SP::GETPCX), GlobalBaseReg);
195  SparcFI->setGlobalBaseReg(GlobalBaseReg);
196  return GlobalBaseReg;
197}
198